WP Offload S3 Lite - Version 1.0

Version Description

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

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

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

Download this release

Release Info

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

Code changes from version 0.9.11 to 1.0

README.md CHANGED
@@ -1,9 +1,9 @@
1
- # WP Offload S3 #
2
  **Contributors:** bradt, deliciousbrains
3
  **Tags:** uploads, amazon, s3, amazon s3, mirror, admin, media, cdn, cloudfront
4
  **Requires at least:** 3.7
5
  **Tested up to:** 4.4
6
- **Stable tag:** 0.9.11
7
  **License:** GPLv3
8
 
9
  Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery.
@@ -54,10 +54,10 @@ You can see the minimum requirements [here](https://deliciousbrains.com/wp-offlo
54
  ## Screenshots ##
55
 
56
  ### 1. Choosing/creating a bucket ###
57
- ![Choosing/creating a bucket](https://raw.githubusercontent.com/deliciousbrains/wp-wp-offload-s3/assets/screenshot-1.png)
58
 
59
  ### 2. Settings screen ###
60
- ![Settings screen](https://raw.githubusercontent.com/deliciousbrains/wp-wp-offload-s3/assets/screenshot-2.png)
61
 
62
 
63
  ## Upgrade Notice ##
@@ -73,6 +73,25 @@ This version requires PHP 5.3.3+ and the Amazon Web Services plugin
73
 
74
  ## Changelog ##
75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  ### WP Offload S3 0.9.11 - 2015-12-19 ###
77
  * Bug fix: Responsive images in post content not working when served from S3
78
  * Bug fix: Responsive images using wrong image size when there are multiple images with the same width
1
+ # WP Offload S3 Lite #
2
  **Contributors:** bradt, deliciousbrains
3
  **Tags:** uploads, amazon, s3, amazon s3, mirror, admin, media, cdn, cloudfront
4
  **Requires at least:** 3.7
5
  **Tested up to:** 4.4
6
+ **Stable tag:** 1.0
7
  **License:** GPLv3
8
 
9
  Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery.
54
  ## Screenshots ##
55
 
56
  ### 1. Choosing/creating a bucket ###
57
+ ![Choosing/creating a bucket](https://raw.githubusercontent.com/deliciousbrains/wp-wp-offload-s3-lite/assets/screenshot-1.png)
58
 
59
  ### 2. Settings screen ###
60
+ ![Settings screen](https://raw.githubusercontent.com/deliciousbrains/wp-wp-offload-s3-lite/assets/screenshot-2.png)
61
 
62
 
63
  ## Upgrade Notice ##
73
 
74
  ## Changelog ##
75
 
76
+ ### WP Offload S3 Lite 1.0 - 2016-03-07 ###
77
+ * New: Plugin renamed to "WP Offload S3 Lite"
78
+ * New: Define any and all settings with a constant in wp-config.php
79
+ * New: Documentation links for each setting
80
+ * Improvement: Simplified domain setting UI
81
+ * Improvement: Far future expiration header set by default
82
+ * Improvement: Newly created bucket now immediately appears in the bucket list
83
+ * Improvement: Cleanup user meta on uninstall
84
+ * Improvement: WP Retina 2x integration [removed](https://deliciousbrains.com/wp-offload-s3/doc/copy-hidpi-2x-images-support/)
85
+ * Bug fix: Year/Month folder structure on S3 not created if the 'Organise my uploads into month and year-based folders' WordPress setting is disabled
86
+ * Bug fix: Responsive srcset PHP notices
87
+ * Bug fix: Compatibility addon notices displayed to non-admin users
88
+ * Bug fix: Potential PHP fatal error in MySQL version check in diagnostic log
89
+ * Bug fix: Missing image library notices displaying before plugin is setup
90
+
91
+ ### WP Offload S3 0.9.12 - 2016-02-03 ###
92
+ * Improvement: Compatibility with WP Offload S3 Assets 1.1
93
+ * Bug fix: Object versioned responsive images in post content not working when served from S3 on WordPress 4.4+
94
+
95
  ### WP Offload S3 0.9.11 - 2015-12-19 ###
96
  * Bug fix: Responsive images in post content not working when served from S3
97
  * Bug fix: Responsive images using wrong image size when there are multiple images with the same width
assets/css/styles.css CHANGED
@@ -1 +1 @@
1
- .aws-main.wrap>h1{float:left}.aws-main.wrap .as3cf-notice,.aws-main.wrap .as3cf-updated,.aws-main.wrap .as3cf-error{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.aws-main.wrap .as3cf-error.fatal{clear:both;float:left}.aws-main.wrap h2.nav-tab-wrapper{float:none;margin-bottom:15px;width:650px;margin-top:10px;padding:9px 0 0 5px}.aws-main.wrap h2.nav-tab-wrapper a.nav-tab-active{color:#464646;cursor:default}.aws-main.wrap h2.nav-tab-wrapper a:focus{-webkit-box-shadow:none;box-shadow:none}.aws-main.wrap .error pre{background:#eaeaea;background:rgba(0,0,0,0.07);display:block;padding:10px 15px}.aws-main.wrap .error pre code{padding:0;background:none}.aws-main.wrap[data-tab="support"] .as3cf-notice,.aws-main.wrap[data-tab="support"] .error,.aws-main.wrap[data-tab="support"] .updated,.aws-main.wrap[data-tab="support"] .updated.show{display:none}.aws-main.wrap[data-tab="support"] .fatal .error,.aws-main.wrap[data-tab="support"] .as3cf-notice.important,.aws-main.wrap[data-tab="support"] .dbrains-api-down{display:block}.aws-main.wrap .as3cf-notice,.aws-main.wrap .error,.aws-main.wrap .updated{max-width:650px;margin-top:15px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.aws-main.wrap .as3cf-updated{display:none}.aws-main.wrap .as3cf-updated.as3cf-notice,.aws-main.wrap .as3cf-updated.show{display:block}.as3cf-tab .as3cf-main-settings{display:none}.as3cf-tab .as3cf-bucket-container{display:block}.as3cf-tab.as3cf-has-bucket .as3cf-main-settings{display:block}.as3cf-tab.as3cf-has-bucket .as3cf-bucket-container{display:none}.as3cf-tab{display:none;position:relative;width:650px}.as3cf-tab .as3cf-main-settings p{font-size:13px}.as3cf-tab .as3cf-main-settings p a{color:#444}.as3cf-tab .object-prefix-desc em{white-space:nowrap}.as3cf-tab .as3cf-url-preview-wrap{background:#fff;text-align:center;padding:20px 0 0;max-width:650px;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.as3cf-tab .as3cf-url-preview-wrap .as3cf-url-preview{margin-top:10px;padding:0 20px 10px;overflow-x:scroll}.as3cf-tab .as3cf-url-preview-wrap span{color:#aaa;text-transform:uppercase;font-weight:bold}.as3cf-tab .as3cf-ssl p.info{margin-top:10px;padding:0}.as3cf-tab .as3cf-radio-group label{display:block;margin-bottom:10px}.as3cf-tab .as3cf-radio-group label.disabled,.as3cf-tab .as3cf-radio-group label.disabled p{color:#bbbbbb;cursor:default}.as3cf-tab .as3cf-radio-group p{padding-left:25px;color:#6b6b6b;margin:0;font-size:12px}.as3cf-tab .as3cf-radio-group p.as3cf-setting{margin-top:5px}.as3cf-tab .as3cf-switch{position:relative;display:inline-block;padding:2px;overflow:hidden;border-radius:2px;-webkit-border-radius:2px;background-color:#d4d3d3;cursor:pointer}.as3cf-tab .as3cf-switch.on{background-color:#ade7b5}.as3cf-tab .as3cf-switch span{visibility:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;display:inline-block;height:100%;font-size:12px;line-height:20px;border-radius:2px;-webkit-border-radius:2px;font-weight:bold;padding:4px 8px;background:#fff;color:#8d8d8d;z-index:1}.as3cf-tab .as3cf-switch span.on{color:#82d78b}.as3cf-tab .as3cf-switch span.checked{visibility:visible}.as3cf-tab .as3cf-switch.disabled{cursor:default;background:#e6e6e6}.as3cf-tab .as3cf-switch.disabled span{background:#f1f1f1;color:#d6d6d6}.as3cf-tab .as3cf-switch input[type="checkbox"]{position:absolute !important;top:0;left:0;opacity:0;filter:alpha(opacity=0);z-index:-1}.as3cf-tab .as3cf-setting.hide{display:none}.as3cf-tab h3{font-weight:normal;text-transform:uppercase;margin:15px 0}.as3cf-tab .form-table{margin:0}.as3cf-tab .form-table tr.as3cf-border-bottom td{border-bottom:1px solid #ddd;padding:20px 0px}.as3cf-tab .form-table tr.as3cf-setting-title td{padding-bottom:0}.as3cf-tab .form-table tr.as3cf-setting-title:first-child td{padding-top:20px}.as3cf-tab .form-table tr td{padding:15px 0}.as3cf-tab .form-table tr td:first-child{vertical-align:top;min-width:120px}.as3cf-tab .form-table tr td .as3cf-notice:last-child{margin-bottom:0}.as3cf-tab .form-table tr:first-of-type td{padding-top:5px}.as3cf-tab .form-table h3{padding:0;margin:0}.as3cf-tab .form-table h4{margin:0}.as3cf-tab .as3cf-active-bucket{font-weight:bold;margin-right:10px}.as3cf-tab .as3cf-view-bucket{color:#444;text-decoration:none;margin-right:10px}.as3cf-tab .as3cf-view-bucket:hover,.as3cf-tab .as3cf-view-bucket:active{color:#00a0d2}.as3cf-tab .as3cf-view-bucket .dashicons-external{margin-top:-2px}.as3cf-tab .tooltip{position:relative;z-index:2;cursor:pointer}.as3cf-tab .tooltip:before,.as3cf-tab .tooltip:after{visibility:hidden;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);opacity:0;pointer-events:none}.as3cf-tab .tooltip:before{position:absolute;bottom:150%;left:50%;margin-bottom:5px;margin-left:-250px;padding:10px;width:500px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;background-color:#000;background-color:rgba(51,51,51,0.9);color:#fff;content:attr(data-tooltip);text-align:center;font-size:14px;line-height:1.3}.as3cf-tab .tooltip:after{position:absolute;bottom:150%;left:50%;margin-left:-5px;width:0;border-top:5px solid #000;border-top:5px solid rgba(51,51,51,0.9);border-right:5px solid transparent;border-left:5px solid transparent;content:" ";font-size:0;line-height:0}.as3cf-tab .tooltip:hover:before,.as3cf-tab .tooltip:hover:after{visibility:visible;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);opacity:1}#tab-media{display:block}#tab-media .as3cf-main-settings{display:none}#tab-media .as3cf-bucket-container{display:block}#tab-media.as3cf-has-bucket .as3cf-main-settings{display:block}#tab-media.as3cf-has-bucket .as3cf-bucket-container{display:none}.as3cf-bucket-container h3{line-height:1.3;text-transform:none}.as3cf-bucket-container a:focus{-webkit-box-shadow:none;box-shadow:none;outline:none}.as3cf-bucket-container input[type=text]{box-sizing:border-box;width:100%}.as3cf-bucket-container select{box-sizing:border-box;width:50%}.as3cf-bucket-container .form-table td{padding:5px 0}.as3cf-bucket-container .form-table td:first-child{width:100px;line-height:30px;vertical-align:top}.as3cf-bucket-container .bucket-actions{margin:15px 0;border-top:1px solid #ccc;padding-top:15px;overflow:hidden}.as3cf-bucket-container .bucket-actions button,.as3cf-bucket-container .bucket-actions .right{float:right;margin-right:0}.as3cf-bucket-container .bucket-actions span{display:inline-block;margin-right:20px;line-height:28px}.as3cf-bucket-container .bucket-actions .bucket-action-cancel{color:#a00;text-decoration:none}.as3cf-bucket-container .bucket-actions .bucket-action-cancel:hover{color:red}.as3cf-bucket-container .as3cf-bucket-list{padding:15px;max-height:200px;overflow-x:hidden;overflow-y:auto;background-color:#fff;font-size:14px}.as3cf-bucket-container .as3cf-bucket-list li:last-of-type{margin-bottom:0}.as3cf-bucket-container .as3cf-bucket-list a{color:#444;text-decoration:none}.as3cf-bucket-container .as3cf-bucket-list a:hover{color:#0074A2}.as3cf-bucket-container .as3cf-bucket-list a.selected{font-weight:bold;color:#0074A2}.as3cf-bucket-container .as3cf-bucket-list a .dashicons{margin-right:5px}.as3cf-bucket-container .as3cf-bucket-select,.as3cf-bucket-container .as3cf-bucket-create{display:none}.as3cf-bucket-container .bucket-actions.select{display:none}.as3cf-tab{display:none}#tab-media{display:block}#tab-support{min-height:900px}#tab-support .as3cf-sidebar{top:11px}#tab-support .support-section{border-bottom:1px solid #ccc;padding-bottom:20px;margin-bottom:20px}#tab-support .debug textarea{width:100%;min-height:200px;font-family:Consolas, Monaco, monospace;margin-bottom:5px}.as3cf-sidebar{position:absolute;top:25px;left:670px;width:292px}.as3cf-sidebar .block{padding:20px;border:1px solid #ccc}.as3cf-sidebar .subscribe{border-top:none}.as3cf-sidebar .subscribe h2{padding:0;margin:0;margin-bottom:0.5em;color:#666;font-size:20px;line-height:1.2em;float:none}.as3cf-sidebar .subscribe h3{font-size:16px;margin:0}.as3cf-sidebar .subscribe p{margin:0}.as3cf-sidebar .subscribe .intro{margin-bottom:1em;line-height:1.4}.as3cf-sidebar .subscribe li{line-height:1.4}.as3cf-sidebar .subscribe .links{margin-bottom:2em}.as3cf-sidebar .subscribe .links a{text-decoration:none}.as3cf-sidebar .subscribe .promise{color:#999;font-size:12px;line-height:1.4em}.as3cf-sidebar .subscribe .field{margin-bottom:0.5em}.as3cf-sidebar .subscribe .field p{margin-bottom:0.3em}.as3cf-sidebar .subscribe .field input[type=text],.as3cf-sidebar .subscribe .field input[type=email]{width:100%}.as3cf-sidebar .subscribe .field.submit-button{margin-bottom:1em}.as3cf-sidebar .credits{border-top:0}.as3cf-sidebar .credits h4{font-size:16px;margin-top:0;margin-bottom:10px}.as3cf-sidebar .credits ul{margin:0}.as3cf-sidebar .credits li{overflow:hidden}.as3cf-sidebar .credits li:last-child{margin-bottom:0}.as3cf-sidebar .credits img{float:left;margin-right:10px}.as3cf-sidebar .credits span{float:left;display:block;line-height:32px}.as3cf-sidebar .credits a{display:block;text-decoration:none;color:#444;font-size:16px;text-align:center}.as3cf-sidebar .credits a:hover{color:#888}@media (min--moz-device-pixel-ratio: 1.3), (-o-min-device-pixel-ratio: 2.6 / 2), (-webkit-min-device-pixel-ratio: 1.3), (min-device-pixel-ratio: 1.3), (min-resolution: 1.3dppx){.as3cf-sidebar .as3cf-banner{background-image:url(../img/snail-banner@2x.jpg);background-size:292px 156px}}@media screen and (max-width: 1052px){.as3cf-sidebar{position:relative;top:auto;right:auto;margin-top:50px}}.as3cf-banner{margin-top:28px;width:292px;height:156px;display:block;background-image:url(../img/snail-banner.jpg);position:relative}.as3cf-banner h1{font-size:28px;color:#fff;font-weight:200;margin:0;position:absolute;bottom:25px;left:20px;text-decoration:none}.as3cf-upgrade-details{background-color:#73833b;padding:20px;color:#fff;font-size:13px;margin:0;display:block;text-decoration:none}.as3cf-upgrade-details p{margin:0}.as3cf-upgrade-details a{color:#fff;font-weight:bold;text-decoration:none;font-size:16px}.as3cf-upgrade-details a:hover{color:#fff;opacity:0.9}.as3cf-upgrade-details ul{margin-top:0;margin-left:16px;list-style-type:disc}.aws-compatibility-notice.error{clear:both;margin:5px 20px 5px 0}.as3cf-bucket-error span.title{font-weight:bold}.as3cf-invalid-bucket-name,.as3cf-validation-error{display:block;margin-top:2px;font-size:12px;color:#a00}
1
+ .aws-main.wrap>h1{float:left}.aws-main.wrap .as3cf-notice,.aws-main.wrap .as3cf-updated,.aws-main.wrap .as3cf-error{-webkit-box-sizing:border-box;box-sizing:border-box}.aws-main.wrap .as3cf-error.fatal{clear:both;float:left}.aws-main.wrap h2.nav-tab-wrapper{float:none;margin-bottom:15px;width:650px;margin-top:10px;padding:9px 0 0 5px}.aws-main.wrap h2.nav-tab-wrapper a.nav-tab-active{color:#464646;cursor:default}.aws-main.wrap h2.nav-tab-wrapper a:focus{-webkit-box-shadow:none;box-shadow:none}.aws-main.wrap .more-info{white-space:nowrap}.aws-main.wrap .error pre{background:#eaeaea;background:rgba(0,0,0,0.07);display:block;padding:10px 15px}.aws-main.wrap .error pre code{padding:0;background:none}.aws-main.wrap[data-tab="support"] .as3cf-notice,.aws-main.wrap[data-tab="support"] .error,.aws-main.wrap[data-tab="support"] .updated,.aws-main.wrap[data-tab="support"] .updated.show{display:none}.aws-main.wrap[data-tab="support"] .fatal .error,.aws-main.wrap[data-tab="support"] .as3cf-notice.important,.aws-main.wrap[data-tab="support"] .dbrains-api-down{display:block}.aws-main.wrap .as3cf-notice,.aws-main.wrap .error,.aws-main.wrap .updated{max-width:650px;margin-top:15px;-webkit-box-sizing:border-box;box-sizing:border-box}.aws-main.wrap .as3cf-updated{display:none}.aws-main.wrap .as3cf-updated.as3cf-notice,.aws-main.wrap .as3cf-updated.show{display:block}.as3cf-tab .as3cf-main-settings{display:none}.as3cf-tab .as3cf-bucket-container{display:block}.as3cf-tab.as3cf-has-bucket .as3cf-main-settings{display:block}.as3cf-tab.as3cf-has-bucket .as3cf-bucket-container{display:none}.as3cf-tab{display:none;position:relative;width:650px}.as3cf-tab .as3cf-main-settings p{font-size:13px}.as3cf-tab .as3cf-main-settings p a{color:#444}.as3cf-tab .object-prefix-desc em{white-space:nowrap}.as3cf-tab .as3cf-url-preview-wrap{background:#fff;text-align:center;padding:20px 0 0;max-width:650px;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.as3cf-tab .as3cf-url-preview-wrap .as3cf-url-preview{margin-top:10px;padding:0 20px 10px;overflow-x:scroll}.as3cf-tab .as3cf-url-preview-wrap span{color:#aaa;text-transform:uppercase;font-weight:bold}.as3cf-tab .as3cf-ssl{margin-top:10px}.as3cf-tab .as3cf-ssl p.info{margin-top:10px;padding:0}.as3cf-tab .as3cf-radio-group label{display:block;margin-bottom:10px}.as3cf-tab .as3cf-radio-group label.disabled,.as3cf-tab .as3cf-radio-group label.disabled p{color:#bbbbbb;cursor:default}.as3cf-tab .as3cf-radio-group p{padding-left:25px;color:#6b6b6b;margin:0;font-size:12px}.as3cf-tab .as3cf-radio-group p.as3cf-setting{margin-top:5px}.as3cf-tab .as3cf-switch{position:relative;display:inline-block;padding:2px;overflow:hidden;border-radius:2px;-webkit-border-radius:2px;background-color:#d4d3d3;cursor:pointer}.as3cf-tab .as3cf-switch.on{background-color:#ade7b5}.as3cf-tab .as3cf-switch span{visibility:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;float:left;display:inline-block;height:100%;font-size:12px;line-height:20px;border-radius:2px;-webkit-border-radius:2px;font-weight:bold;padding:4px 8px;background:#fff;color:#8d8d8d;z-index:1}.as3cf-tab .as3cf-switch span.on{color:#82d78b}.as3cf-tab .as3cf-switch span.checked{visibility:visible}.as3cf-tab .as3cf-switch.disabled{cursor:default;background:#e6e6e6}.as3cf-tab .as3cf-switch.disabled span{background:#f1f1f1;color:#d6d6d6}.as3cf-tab .as3cf-switch input[type="checkbox"]{position:absolute !important;top:0;left:0;opacity:0;filter:alpha(opacity=0);z-index:-1}.as3cf-tab .as3cf-setting.hide{display:none}.as3cf-tab h3{font-weight:normal;text-transform:uppercase;margin:15px 0}.as3cf-tab .form-table{margin:0}.as3cf-tab .form-table tr.as3cf-border-bottom td{border-bottom:1px solid #ddd;padding:20px 0px}.as3cf-tab .form-table tr.as3cf-setting-title td{padding-bottom:0}.as3cf-tab .form-table tr.as3cf-setting-title:first-child td{padding-top:20px}.as3cf-tab .form-table tr td{padding:15px 0}.as3cf-tab .form-table tr td:first-child{vertical-align:top;min-width:120px}.as3cf-tab .form-table tr td .as3cf-notice:last-child{margin-bottom:0}.as3cf-tab .form-table tr td>p:first-child{margin-top:0}.as3cf-tab .form-table tr:first-of-type td{padding-top:5px}.as3cf-tab .form-table tr.as3cf-bucket-setting .as3cf-defined-in-config{float:none}.as3cf-tab .form-table h3{padding:0;margin:0}.as3cf-tab .form-table h4{margin:0}.as3cf-tab .as3cf-active-bucket{font-weight:bold;margin-right:10px}.as3cf-tab .as3cf-view-bucket{color:#444;text-decoration:none;margin-right:10px}.as3cf-tab .as3cf-view-bucket:hover,.as3cf-tab .as3cf-view-bucket:active{color:#00a0d2}.as3cf-tab .as3cf-view-bucket:focus{-webkit-box-shadow:none;box-shadow:none}.as3cf-tab .as3cf-view-bucket .dashicons-external{margin-top:-2px}.as3cf-tab .tooltip{position:relative;z-index:2;cursor:pointer}.as3cf-tab .tooltip:before,.as3cf-tab .tooltip:after{visibility:hidden;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);opacity:0;pointer-events:none}.as3cf-tab .tooltip:before{position:absolute;bottom:150%;left:50%;margin-bottom:5px;margin-left:-250px;padding:10px;width:500px;-webkit-border-radius:3px;border-radius:3px;background-color:#000;background-color:rgba(51,51,51,0.9);color:#fff;content:attr(data-tooltip);text-align:center;font-size:14px;line-height:1.3}.as3cf-tab .tooltip:after{position:absolute;bottom:150%;left:50%;margin-left:-5px;width:0;border-top:5px solid #000;border-top:5px solid rgba(51,51,51,0.9);border-right:5px solid transparent;border-left:5px solid transparent;content:" ";font-size:0;line-height:0}.as3cf-tab .tooltip:hover:before,.as3cf-tab .tooltip:hover:after{visibility:visible;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);opacity:1}.as3cf-tab .as3cf-defined-in-config{background:#ccc;color:#fff;padding:2px 5px;margin:0 0 5px 5px;float:right}.as3cf-tab .as3cf-defined-setting{color:#bbb}.as3cf-tab .as3cf-defined-setting label{cursor:default}.as3cf-tab .as3cf-defined-setting p .more-info a{color:#bbb}.as3cf-tab .as3cf-defined-setting .as3cf-radio-group p{color:#bbb}.as3cf-tab .as3cf-defined-setting .as3cf-notice{display:none !important}#tab-media{display:block}#tab-media .as3cf-main-settings{display:none}#tab-media .as3cf-bucket-container{display:block}#tab-media.as3cf-has-bucket .as3cf-main-settings{display:block}#tab-media.as3cf-has-bucket .as3cf-bucket-container{display:none}.as3cf-bucket-container h3{line-height:1.3;text-transform:none}.as3cf-bucket-container a:focus{-webkit-box-shadow:none;box-shadow:none;outline:none}.as3cf-bucket-container input[type=text]{-webkit-box-sizing:border-box;box-sizing:border-box;width:100%}.as3cf-bucket-container select{-webkit-box-sizing:border-box;box-sizing:border-box;width:50%}.as3cf-bucket-container .form-table td{padding:5px 0}.as3cf-bucket-container .form-table td:first-child{width:100px;line-height:30px;vertical-align:top}.as3cf-bucket-container .bucket-actions{margin:15px 0;border-top:1px solid #ccc;padding-top:15px;overflow:hidden}.as3cf-bucket-container .bucket-actions button,.as3cf-bucket-container .bucket-actions .right{float:right;margin-right:0}.as3cf-bucket-container .bucket-actions span{display:inline-block;margin-right:20px;line-height:28px}.as3cf-bucket-container .bucket-actions .bucket-action-cancel{color:#a00;text-decoration:none}.as3cf-bucket-container .bucket-actions .bucket-action-cancel:hover{color:red}.as3cf-bucket-container .as3cf-bucket-list{padding:15px;max-height:200px;overflow-x:hidden;overflow-y:auto;background-color:#fff;font-size:14px}.as3cf-bucket-container .as3cf-bucket-list li:last-of-type{margin-bottom:0}.as3cf-bucket-container .as3cf-bucket-list a{color:#444;text-decoration:none}.as3cf-bucket-container .as3cf-bucket-list a:hover{color:#0074A2}.as3cf-bucket-container .as3cf-bucket-list a.selected{font-weight:bold;color:#0074A2}.as3cf-bucket-container .as3cf-bucket-list a .dashicons{margin-right:5px}.as3cf-bucket-container .as3cf-bucket-select,.as3cf-bucket-container .as3cf-bucket-create{display:none}.as3cf-bucket-container .bucket-actions.select{display:none}.as3cf-tab{display:none}#tab-media{display:block}#tab-support{min-height:900px}#tab-support .as3cf-sidebar{top:11px}#tab-support .support-section{border-bottom:1px solid #ccc;padding-bottom:20px;margin-bottom:20px}#tab-support .debug textarea{width:100%;min-height:200px;font-family:Consolas, Monaco, monospace;margin-bottom:5px}.as3cf-sidebar{position:absolute;top:25px;left:670px;width:292px}.as3cf-sidebar .block{padding:20px;border:1px solid #ccc}.as3cf-sidebar .subscribe{border-top:none}.as3cf-sidebar .subscribe h2{padding:0;margin:0;margin-bottom:0.5em;color:#666;font-size:20px;line-height:1.2em;float:none}.as3cf-sidebar .subscribe h3{font-size:16px;margin:0}.as3cf-sidebar .subscribe p{margin:0}.as3cf-sidebar .subscribe .intro{margin-bottom:1em;line-height:1.4}.as3cf-sidebar .subscribe li{line-height:1.4}.as3cf-sidebar .subscribe .links{margin-bottom:2em}.as3cf-sidebar .subscribe .links a{text-decoration:none}.as3cf-sidebar .subscribe .promise{color:#999;font-size:12px;line-height:1.4em}.as3cf-sidebar .subscribe .field{margin-bottom:0.5em}.as3cf-sidebar .subscribe .field p{margin-bottom:0.3em}.as3cf-sidebar .subscribe .field input[type=text],.as3cf-sidebar .subscribe .field input[type=email]{width:100%}.as3cf-sidebar .subscribe .field.submit-button{margin-bottom:1em}.as3cf-sidebar .credits{border-top:0}.as3cf-sidebar .credits h4{font-size:16px;margin-top:0;margin-bottom:10px}.as3cf-sidebar .credits ul{margin:0}.as3cf-sidebar .credits li{overflow:hidden}.as3cf-sidebar .credits li:last-child{margin-bottom:0}.as3cf-sidebar .credits img{float:left;margin-right:10px}.as3cf-sidebar .credits span{float:left;display:block;line-height:32px}.as3cf-sidebar .credits a{display:block;text-decoration:none;color:#444;font-size:16px;text-align:center}.as3cf-sidebar .credits a:hover{color:#888}@media (min--moz-device-pixel-ratio: 1.3), (-webkit-min-device-pixel-ratio: 1.3), (min-device-pixel-ratio: 1.3), (min-resolution: 1.3dppx){.as3cf-sidebar .as3cf-banner{background-image:url(../img/snail-banner@2x.jpg);background-size:292px 156px}}@media screen and (max-width: 1052px){.as3cf-sidebar{position:relative;top:auto;right:auto;margin-top:50px}}.as3cf-banner{margin-top:28px;width:292px;height:156px;display:block;background-image:url(../img/snail-banner.jpg);position:relative}.as3cf-banner h1{font-size:28px;color:#fff;font-weight:200;margin:0;position:absolute;bottom:25px;left:20px;text-decoration:none}.as3cf-upgrade-details{background-color:#73833b;padding:20px;color:#fff;font-size:13px;margin:0;display:block;text-decoration:none}.as3cf-upgrade-details p{margin:0}.as3cf-upgrade-details a{color:#fff;font-weight:bold;text-decoration:none;font-size:16px}.as3cf-upgrade-details a:hover{color:#fff;opacity:0.9}.as3cf-upgrade-details ul{margin-top:0;margin-left:16px;list-style-type:disc}.aws-compatibility-notice.error{clear:both;margin:5px 20px 5px 0}.as3cf-bucket-error span.title{font-weight:bold}.as3cf-invalid-bucket-name,.as3cf-validation-error{display:block;margin-top:2px;font-size:12px;color:#a00}.as3cf-notice-toggle-content{max-height:100px;overflow-y:scroll}.as3cf-notice-toggle-content .as3cf-notice-toggle-list{margin-top:0;margin-left:0;padding-left:26px;color:#dc3232}
assets/js/modal.js CHANGED
@@ -1,4 +1,4 @@
1
- var as3cfModal = (function ( $ ) {
2
 
3
  var modal = {
4
  prefix: 'as3cf',
@@ -18,6 +18,27 @@ var as3cfModal = (function ( $ ) {
18
  return target.replace( /[^a-z]/g, '' );
19
  }
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  /**
22
  * Open modal
23
  *
@@ -25,7 +46,7 @@ var as3cfModal = (function ( $ ) {
25
  * @param {function} callback
26
  * @param {string} customClass
27
  */
28
- modal.open = function ( target, callback, customClass ) {
29
  var key = targetToKey( target );
30
 
31
  // Overlay
@@ -66,14 +87,14 @@ var as3cfModal = (function ( $ ) {
66
  *
67
  * @param {function} callback
68
  */
69
- modal.close = function ( callback ) {
70
  if ( modal.loading ) {
71
  return;
72
  }
73
 
74
  var target = $( '#as3cf-modal' ).data( 'as3cf-modal-target' );
75
 
76
- $( '#as3cf-overlay' ).fadeOut( 150, function () {
77
  if ( 'function' === typeof callback ) {
78
  callback( target );
79
  }
@@ -91,19 +112,19 @@ var as3cfModal = (function ( $ ) {
91
  *
92
  * @param {bool} state
93
  */
94
- modal.setLoadingState = function ( state ) {
95
  modal.loading = state;
96
  };
97
 
98
  // Setup click handlers
99
- $( document ).ready( function () {
100
 
101
- $( 'body' ).on( 'click', '[data-as3cf-modal]', function ( e ) {
102
  e.preventDefault();
103
  modal.open( $( this ).data( 'as3cf-modal' ) + '.' + modal.prefix );
104
  } );
105
 
106
- $( 'body' ).on( 'click', '#as3cf-overlay, .close-as3cf-modal', function ( e ) {
107
  e.preventDefault();
108
 
109
  // Don't allow children to bubble up click event
@@ -118,4 +139,4 @@ var as3cfModal = (function ( $ ) {
118
 
119
  return modal;
120
 
121
- })( jQuery );
1
+ var as3cfModal = (function( $ ) {
2
 
3
  var modal = {
4
  prefix: 'as3cf',
18
  return target.replace( /[^a-z]/g, '' );
19
  }
20
 
21
+ /**
22
+ * Check if modal exists in DOM or in Memory.
23
+ *
24
+ * @param {string} target
25
+ *
26
+ * @return {boolean}
27
+ */
28
+ modal.exists = function( target ) {
29
+ var key = targetToKey( target );
30
+
31
+ if ( undefined !== modals[ key ] ) {
32
+ return true;
33
+ }
34
+
35
+ if ( $( target ).length ) {
36
+ return true;
37
+ }
38
+
39
+ return false;
40
+ };
41
+
42
  /**
43
  * Open modal
44
  *
46
  * @param {function} callback
47
  * @param {string} customClass
48
  */
49
+ modal.open = function( target, callback, customClass ) {
50
  var key = targetToKey( target );
51
 
52
  // Overlay
87
  *
88
  * @param {function} callback
89
  */
90
+ modal.close = function( callback ) {
91
  if ( modal.loading ) {
92
  return;
93
  }
94
 
95
  var target = $( '#as3cf-modal' ).data( 'as3cf-modal-target' );
96
 
97
+ $( '#as3cf-overlay' ).fadeOut( 150, function() {
98
  if ( 'function' === typeof callback ) {
99
  callback( target );
100
  }
112
  *
113
  * @param {bool} state
114
  */
115
+ modal.setLoadingState = function( state ) {
116
  modal.loading = state;
117
  };
118
 
119
  // Setup click handlers
120
+ $( document ).ready( function() {
121
 
122
+ $( 'body' ).on( 'click', '[data-as3cf-modal]', function( e ) {
123
  e.preventDefault();
124
  modal.open( $( this ).data( 'as3cf-modal' ) + '.' + modal.prefix );
125
  } );
126
 
127
+ $( 'body' ).on( 'click', '#as3cf-overlay, .close-as3cf-modal', function( e ) {
128
  e.preventDefault();
129
 
130
  // Don't allow children to bubble up click event
139
 
140
  return modal;
141
 
142
+ })( jQuery );
assets/js/modal.min.js CHANGED
@@ -1 +1 @@
1
- var as3cfModal=function(a){function b(a){return a.replace(/[^a-z]/g,"")}var c={prefix:"as3cf",loading:!1},d={};return c.open=function(c,e,f){var g=b(c);a("body").append('<div id="as3cf-overlay"></div>');var h=a("#as3cf-overlay");h.append('<div id="as3cf-modal"><span class="close-as3cf-modal">×</span></div>');var i=a("#as3cf-modal");if(void 0===d[g]){var j=a(c);d[g]=j.clone(!0).css("display","block"),j.remove()}i.data("as3cf-modal-target",c).append(d[g]),void 0!==f&&i.addClass(f),"function"==typeof e&&e(c),a("body").addClass("as3cf-modal-open"),h.fadeIn(150),i.fadeIn(150),a("body").trigger("as3cf-modal-open",[c])},c.close=function(b){if(!c.loading){var d=a("#as3cf-modal").data("as3cf-modal-target");a("#as3cf-overlay").fadeOut(150,function(){"function"==typeof b&&b(d),a("body").removeClass("as3cf-modal-open"),a(this).remove()}),a("body").trigger("as3cf-modal-close",[d])}},c.setLoadingState=function(a){c.loading=a},a(document).ready(function(){a("body").on("click","[data-as3cf-modal]",function(b){b.preventDefault(),c.open(a(this).data("as3cf-modal")+"."+c.prefix)}),a("body").on("click","#as3cf-overlay, .close-as3cf-modal",function(a){return a.preventDefault(),a.target!==this?!1:void c.close()})}),c}(jQuery);
1
+ var as3cfModal=function(a){function b(a){return a.replace(/[^a-z]/g,"")}var c={prefix:"as3cf",loading:!1},d={};return c.exists=function(c){var e=b(c);return void 0!==d[e]?!0:!!a(c).length},c.open=function(c,e,f){var g=b(c);a("body").append('<div id="as3cf-overlay"></div>');var h=a("#as3cf-overlay");h.append('<div id="as3cf-modal"><span class="close-as3cf-modal">×</span></div>');var i=a("#as3cf-modal");if(void 0===d[g]){var j=a(c);d[g]=j.clone(!0).css("display","block"),j.remove()}i.data("as3cf-modal-target",c).append(d[g]),void 0!==f&&i.addClass(f),"function"==typeof e&&e(c),a("body").addClass("as3cf-modal-open"),h.fadeIn(150),i.fadeIn(150),a("body").trigger("as3cf-modal-open",[c])},c.close=function(b){if(!c.loading){var d=a("#as3cf-modal").data("as3cf-modal-target");a("#as3cf-overlay").fadeOut(150,function(){"function"==typeof b&&b(d),a("body").removeClass("as3cf-modal-open"),a(this).remove()}),a("body").trigger("as3cf-modal-close",[d])}},c.setLoadingState=function(a){c.loading=a},a(document).ready(function(){a("body").on("click","[data-as3cf-modal]",function(b){b.preventDefault(),c.open(a(this).data("as3cf-modal")+"."+c.prefix)}),a("body").on("click","#as3cf-overlay, .close-as3cf-modal",function(a){return a.preventDefault(),a.target!==this?!1:void c.close()})}),c}(jQuery);
assets/js/notice.js CHANGED
@@ -1,24 +1,37 @@
1
  (function( $ ) {
2
 
3
- $( 'body' ).on( 'click', '.as3cf-notice .notice-dismiss', function( e ) {
 
 
4
  var id = $( this ).parents( '.as3cf-notice' ).attr( 'id' );
5
  if ( id ) {
6
  var data = {
7
- action : 'as3cf-dismiss-notice',
8
  notice_id: id,
9
- _nonce : as3cf_notice.nonces.dismiss_notice
10
  };
11
 
12
  $.ajax( {
13
- url : ajaxurl,
14
- type : 'POST',
15
  dataType: 'JSON',
16
- data : data,
17
- error : function( jqXHR, textStatus, errorThrown ) {
18
  alert( as3cf_notice.strings.dismiss_notice_error + errorThrown );
19
  }
20
  } );
21
  }
22
  } );
23
 
24
- })( jQuery );
 
 
 
 
 
 
 
 
 
 
 
1
  (function( $ ) {
2
 
3
+ var $body = $( 'body' );
4
+
5
+ $body.on( 'click', '.as3cf-notice .notice-dismiss', function( e ) {
6
  var id = $( this ).parents( '.as3cf-notice' ).attr( 'id' );
7
  if ( id ) {
8
  var data = {
9
+ action: 'as3cf-dismiss-notice',
10
  notice_id: id,
11
+ _nonce: as3cf_notice.nonces.dismiss_notice
12
  };
13
 
14
  $.ajax( {
15
+ url: ajaxurl,
16
+ type: 'POST',
17
  dataType: 'JSON',
18
+ data: data,
19
+ error: function( jqXHR, textStatus, errorThrown ) {
20
  alert( as3cf_notice.strings.dismiss_notice_error + errorThrown );
21
  }
22
  } );
23
  }
24
  } );
25
 
26
+ $body.on( 'click', '.as3cf-notice-toggle', function( e ) {
27
+ e.preventDefault();
28
+ var $link = $( this );
29
+ var label = $link.data( 'hide' );
30
+
31
+ $link.data( 'hide', $link.html() );
32
+ $link.html( label );
33
+
34
+ $link.closest( '.as3cf-notice' ).find( '.as3cf-notice-toggle-content' ).toggle();
35
+ } );
36
+
37
+ })( jQuery );
assets/js/notice.min.js CHANGED
@@ -1 +1 @@
1
- !function(a){a("body").on("click",".as3cf-notice .notice-dismiss",function(b){var c=a(this).parents(".as3cf-notice").attr("id");if(c){var d={action:"as3cf-dismiss-notice",notice_id:c,_nonce:as3cf_notice.nonces.dismiss_notice};a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:d,error:function(a,b,c){alert(as3cf_notice.strings.dismiss_notice_error+c)}})}})}(jQuery);
1
+ !function(a){var b=a("body");b.on("click",".as3cf-notice .notice-dismiss",function(b){var c=a(this).parents(".as3cf-notice").attr("id");if(c){var d={action:"as3cf-dismiss-notice",notice_id:c,_nonce:as3cf_notice.nonces.dismiss_notice};a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:d,error:function(a,b,c){alert(as3cf_notice.strings.dismiss_notice_error+c)}})}}),b.on("click",".as3cf-notice-toggle",function(b){b.preventDefault();var c=a(this),d=c.data("hide");c.data("hide",c.html()),c.html(d),c.closest(".as3cf-notice").find(".as3cf-notice-toggle-content").toggle()})}(jQuery);
assets/js/script.js CHANGED
@@ -2,6 +2,7 @@
2
 
3
  var savedSettings = {};
4
  var bucketNamePattern = /[^a-z0-9.-]/;
 
5
 
6
  var $tabs = $( '.as3cf-tab' );
7
  var $activeTab;
@@ -24,7 +25,7 @@
24
  * @param string checkbox_wrap
25
  */
26
  function setCheckbox( checkbox_wrap ) {
27
- var $switch = $( '#' + checkbox_wrap );
28
  var $checkbox = $switch.find( 'input[type=checkbox]' );
29
 
30
  $switch.toggleClass( 'on' ).find( 'span' ).toggleClass( 'checked' );
@@ -38,7 +39,7 @@
38
  * @param {object} $input
39
  */
40
  function validateCustomDomain( $input ) {
41
- var $error = $input.next( '.as3cf-validation-error' );
42
  var $submit = $( '#' + $activeTab.attr( 'id' ) + ' form button[type="submit"]' );
43
  var pattern = /[^a-zA-Z0-9\.\-]/;
44
 
@@ -69,7 +70,7 @@
69
  if ( $activeTab.attr( 'data-prefix' ) ) {
70
  as3cfModal.prefix = $activeTab.attr( 'data-prefix' );
71
  }
72
- if ( !persist_updated_notice ) {
73
  $( '.as3cf-updated' ).removeClass( 'show' );
74
  }
75
  }
@@ -121,18 +122,18 @@
121
  var that = this;
122
 
123
  $.ajax( {
124
- url : ajaxurl,
125
- type : 'POST',
126
  dataType: 'JSON',
127
- data : data,
128
- error : function( jqXHR, textStatus, errorThrown ) {
129
  $bucketList.html( '' );
130
  that.showError( as3cf.strings.get_buckets_error, errorThrown, 'as3cf-bucket-select' );
131
  },
132
- success : function( data, textStatus, jqXHR ) {
133
  $bucketList.html( '' );
134
 
135
- if ( typeof data[ 'success' ] !== 'undefined' ) {
136
  $( '.as3cf-bucket-error' ).hide();
137
 
138
  $( data[ 'buckets' ] ).each( function( idx, bucket ) {
@@ -176,7 +177,9 @@
176
  $bucketContainer.find( '.as3cf-bucket-select' ).show().siblings().hide();
177
  $bucketContainer.find( '.bucket-actions.select' ).show().siblings( '.bucket-actions' ).hide();
178
 
179
- this.loadList();
 
 
180
  }
181
 
182
  $bucketContainer.find( '.as3cf-bucket-error' ).hide();
@@ -210,29 +213,32 @@
210
  $manualBucketButton.prop( 'disabled', true );
211
 
212
  var data = {
213
- action : as3cfModal.prefix + '-manual-save-bucket',
214
  bucket_name: bucketName,
215
- _nonce : window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.manual_bucket
216
  };
217
 
218
  var that = this;
219
 
220
  $.ajax( {
221
- url : ajaxurl,
222
- type : 'POST',
223
  dataType: 'JSON',
224
- data : data,
225
- error : function( jqXHR, textStatus, errorThrown ) {
226
  $manualBucketButton.text( originalBucketText );
227
  that.showError( as3cf.strings.save_bucket_error, errorThrown, 'as3cf-bucket-manual' );
228
  },
229
- success : function( data, textStatus, jqXHR ) {
230
  $manualBucketButton.text( originalBucketText );
231
  $manualBucketButton.prop( 'disabled', false );
232
- if ( typeof data[ 'success' ] !== 'undefined' ) {
233
  that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
234
  $( '#' + as3cfModal.prefix + '-bucket-select' ).val( 'manual' );
235
  $( '.as3cf-bucket-list a' ).removeClass( 'selected' ).filter( '[data-bucket="' + bucketName + '"]' ).addClass( 'selected' );
 
 
 
236
  } else {
237
  that.showError( as3cf.strings.save_bucket_error, data[ 'error' ], 'as3cf-bucket-manual' );
238
  }
@@ -249,6 +255,7 @@
249
  var $bucketList = $( '.as3cf-bucket-list' );
250
 
251
  if ( this.bucketSelectLock ) {
 
252
  // Bail if a bucket has already been clicked
253
  return;
254
  }
@@ -272,28 +279,28 @@
272
  var bucketName = $link.attr( 'data-bucket' );
273
 
274
  var data = {
275
- action : as3cfModal.prefix + '-save-bucket',
276
  bucket_name: bucketName,
277
- _nonce : window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.save_bucket
278
  };
279
 
280
  var that = this;
281
 
282
  $.ajax( {
283
- url : ajaxurl,
284
- type : 'POST',
285
  dataType: 'JSON',
286
- data : data,
287
- error : function( jqXHR, textStatus, errorThrown ) {
288
  $bucketList.removeClass( 'saving' );
289
  that.showError( as3cf.strings.save_bucket_error, errorThrown, 'as3cf-bucket-select' );
290
  $( '.as3cf-bucket-list a' ).removeClass( 'selected' );
291
  $( '.as3cf-bucket-list a[data-bucket="' + previousBucket + '"]' ).addClass( 'selected' );
292
  },
293
- success : function( data, textStatus, jqXHR ) {
294
  $link.find( '.spinner' ).hide().css( 'visibility', 'hidden' );
295
  $bucketList.removeClass( 'saving' );
296
- if ( typeof data[ 'success' ] !== 'undefined' ) {
297
  that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
298
  $( '#' + as3cfModal.prefix + '-bucket-select' ).val( '' );
299
  } else {
@@ -318,15 +325,13 @@
318
 
319
  if ( $createBucketForm.find( '.as3cf-bucket-name' ).val().length < 3 ) {
320
  $createBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
321
- }
322
- else {
323
  $createBucketForm.find( 'button[type=submit]' ).attr( 'disabled', false );
324
  }
325
 
326
  if ( $manualBucketForm.find( '.as3cf-bucket-name' ).val().length < 3 ) {
327
  $manualBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
328
- }
329
- else {
330
  $manualBucketForm.find( 'button[type=submit]' ).attr( 'disabled', false );
331
  }
332
  },
@@ -342,7 +347,7 @@
342
  var $activeView = $( '.as3cf-bucket-container' ).children( ':visible' );
343
  var $bucketError = $activeView.find( '.as3cf-bucket-error' );
344
 
345
- context = ('undefined' === typeof context) ? null : context;
346
 
347
  if ( context && ! $activeView.hasClass( context ) ) {
348
  return;
@@ -368,11 +373,12 @@
368
  var $activeBucket = $( '#' + as3cfModal.prefix + '-active-bucket' );
369
 
370
  if ( 'as3cf' === as3cfModal.prefix && 0 === $activeBucket.text().trim().length ) {
371
- // first time bucket select - enable main options by default
 
372
  setCheckbox( 'copy-to-s3-wrap' );
373
  setCheckbox( 'serve-from-s3-wrap' );
374
 
375
- // update the saved settings string so we don't trigger the navigation alert
376
  var id = $activeTab.attr( 'id' );
377
  savedSettings[ id ] = serializedForm( id );
378
  }
@@ -387,7 +393,8 @@
387
  $( '.updated' ).not( '.as3cf-notice' ).show();
388
 
389
  $activeTab.addClass( 'as3cf-has-bucket' );
390
- // check permission on bucket
 
391
  $activeTab.find( '.as3cf-can-write-error' ).toggle( ! canWrite );
392
  $activeTab.find( '.as3cf-bucket-error' ).hide();
393
 
@@ -417,9 +424,9 @@
417
  $createBucketButton.prop( 'disabled', true );
418
 
419
  var data = {
420
- action : as3cfModal.prefix + '-create-bucket',
421
  bucket_name: bucketName,
422
- _nonce : window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.create_bucket
423
  };
424
 
425
  if ( $createBucketSelect.val() ) {
@@ -429,24 +436,28 @@
429
  var that = this;
430
 
431
  $.ajax( {
432
- url : ajaxurl,
433
- type : 'POST',
434
  dataType: 'JSON',
435
- data : data,
436
- error : function( jqXHR, textStatus, errorThrown ) {
437
  $createBucketButton.text( origButtonText );
438
  that.showError( as3cf.strings.create_bucket_error, errorThrown, 'as3cf-bucket-create' );
439
  },
440
- success : function( data, textStatus, jqXHR ) {
441
  $createBucketButton.text( origButtonText );
442
  $createBucketButton.prop( 'disabled', false );
443
- if ( typeof data[ 'success' ] !== 'undefined' ) {
444
  that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
445
- // tidy up create bucket form
 
446
  $( '.as3cf-bucket-select-region' ).hide();
447
  $( '.as3cf-bucket-select-region' ).removeAttr( 'selected' );
448
  $createBucketInput.val( '' );
449
  $createBucketButton.attr( 'disabled', true );
 
 
 
450
  } else {
451
  that.showError( as3cf.strings.create_bucket_error, data[ 'error' ], 'as3cf-bucket-create' );
452
  }
@@ -533,10 +544,10 @@
533
  var n = o.name,
534
  v = o.value;
535
  n = n.replace( '[]', '' );
536
- data[ n ] = data[ n ] === undefined ? v : $.isArray( data[ n ] ) ? data[ n ].concat( v ) : [ data[ n ], v ];
537
  } );
538
 
539
- // overwrite the save action stored in the form
540
  data[ 'action' ] = 'as3cf-get-url-preview';
541
 
542
  $.ajax( {
@@ -548,7 +559,7 @@
548
  alert( as3cf.strings.get_url_preview_error + errorThrown );
549
  },
550
  success: function( data, textStatus, jqXHR ) {
551
- if ( typeof data[ 'success' ] !== 'undefined' ) {
552
  $( '.as3cf-url-preview' ).html( data[ 'url' ] );
553
  } else {
554
  alert( as3cf.strings.get_url_preview_error + data[ 'error' ] );
@@ -561,6 +572,7 @@
561
  * Reset the bucket select lock
562
  */
563
  function unlockBucketSelect( target ) {
 
564
  // Unlock setting the bucket
565
  as3cf.buckets.bucketSelectLock = false;
566
  }
@@ -596,12 +608,13 @@
596
  var $navTabs = $( '.wrap.aws-main .nav-tab-wrapper' );
597
  $( '.aws-compatibility-notice, div.updated, div.error, div.notice' ).not( '.below-h2, .inline' ).insertAfter( $navTabs );
598
 
599
- // check for hash in url and switch tabs accordingly
600
  if ( window.location.hash ) {
601
  var hash = window.location.hash.substring( 1 );
602
  as3cf.tabs.toggle( hash, true );
603
  } else {
604
- // default settings tab
 
605
  $activeTab = $( '#tab-' + as3cf.tabs.defaultTab );
606
  $( '.aws-main' ).attr( 'data-tab', as3cf.tabs.defaultTab );
607
  }
@@ -614,9 +627,11 @@
614
  var nextTab = $( this ).attr( 'data-tab' );
615
  as3cf.tabs.toggle( nextTab );
616
  if ( 'media' === nextTab ) {
 
617
  // As it's the default remove the hash
618
  window.location.hash = '';
619
- if ( typeof window.history.replaceState === 'function' && '#' === window.location.href.slice( -1 ) ) {
 
620
  // Strip the # if still on the end of the URL
621
  history.replaceState( {}, '', window.location.href.slice( 0, -1 ) );
622
  }
@@ -628,14 +643,14 @@
628
  // Settings
629
  // --------------------
630
 
631
- // save the original state of the forms for comparison later
632
  if ( $tabs.length ) {
633
  $tabs.each( function( i, tab ) {
634
  savedSettings[ tab.id ] = serializedForm( tab.id );
635
  } );
636
  }
637
 
638
- // prompt user with dialog if leaving the settings page with unsaved changes
639
  $( window ).on( 'beforeunload.as3cf-settings', function() {
640
  if ( $.isEmptyObject( savedSettings ) ) {
641
  return;
@@ -648,14 +663,15 @@
648
  }
649
  } );
650
 
651
- // let the save settings submit happen as normal
652
  $( document ).on( 'submit', '.as3cf-main-settings form', function( e ) {
653
- // disable unload warning
 
654
  $( window ).off( 'beforeunload.as3cf-settings' );
655
  } );
656
 
657
  $( '.as3cf-switch' ).on( 'click', function( e ) {
658
- if ( !$( this ).hasClass( 'disabled' ) ) {
659
  setCheckbox( $( this ).attr( 'id' ) );
660
  }
661
  } );
@@ -670,15 +686,19 @@
670
  var domain = $selected.val();
671
  var $cloudfront = $( this ).parents( '.as3cf-domain' ).find( '.as3cf-setting.cloudfront' );
672
  var cloudfrontSelected = ( 'cloudfront' === domain );
673
- $cloudfront.toggleClass( 'hide', !cloudfrontSelected );
674
  } );
675
 
676
  $( '.as3cf-ssl' ).on( 'change', 'input[type="radio"]', function( e ) {
 
 
 
 
677
  var ssl = $( 'input:radio[name="ssl"]:checked' ).val();
678
  if ( 'https' === ssl ) {
679
  var domain = $( 'input:radio[name="domain"]:checked' ).val();
680
  if ( 'subdomain' === domain ) {
681
- $( 'input[name="domain"][value="path"]' ).attr( "checked", true );
682
  }
683
  $( '.subdomain-wrap input' ).attr( 'disabled', true );
684
  $( '.subdomain-wrap' ).addClass( 'disabled' );
@@ -709,7 +729,6 @@
709
 
710
  return false;
711
  }
712
-
713
  } );
714
 
715
  // Validate custom domain
@@ -748,7 +767,8 @@
748
  $( 'body' ).on( 'click', '.bucket-action-browse', function( e ) {
749
  e.preventDefault();
750
  $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-bucket-select' ).show().siblings().hide();
751
- as3cf.buckets.loadList();
 
752
  } );
753
  $( 'body' ).on( 'click', '.bucket-action-create', function( e ) {
754
  e.preventDefault();
@@ -795,11 +815,14 @@
795
  // Modal open
796
  $( 'body' ).on( 'as3cf-modal-open', function( e, target ) {
797
  if ( '.as3cf-bucket-container.' + as3cfModal.prefix === target ) {
 
798
  // Reset modal
799
  as3cf.buckets.resetModal();
 
800
  // Change manual title text
801
  var title = $( '.as3cf-bucket-manual h3' ).data( 'modal-title' );
802
  $( '.as3cf-bucket-manual h3' ).text( title );
 
803
  // Hide buttons
804
  as3cf.buckets.disabledButtons();
805
  }
2
 
3
  var savedSettings = {};
4
  var bucketNamePattern = /[^a-z0-9.-]/;
5
+ var refreshBucketListOnLoad = false;
6
 
7
  var $tabs = $( '.as3cf-tab' );
8
  var $activeTab;
25
  * @param string checkbox_wrap
26
  */
27
  function setCheckbox( checkbox_wrap ) {
28
+ var $switch = $activeTab.find( '#' + checkbox_wrap );
29
  var $checkbox = $switch.find( 'input[type=checkbox]' );
30
 
31
  $switch.toggleClass( 'on' ).find( 'span' ).toggleClass( 'checked' );
39
  * @param {object} $input
40
  */
41
  function validateCustomDomain( $input ) {
42
+ var $error = $input.next( '.as3cf-validation-error' );
43
  var $submit = $( '#' + $activeTab.attr( 'id' ) + ' form button[type="submit"]' );
44
  var pattern = /[^a-zA-Z0-9\.\-]/;
45
 
70
  if ( $activeTab.attr( 'data-prefix' ) ) {
71
  as3cfModal.prefix = $activeTab.attr( 'data-prefix' );
72
  }
73
+ if ( ! persist_updated_notice ) {
74
  $( '.as3cf-updated' ).removeClass( 'show' );
75
  }
76
  }
122
  var that = this;
123
 
124
  $.ajax( {
125
+ url: ajaxurl,
126
+ type: 'POST',
127
  dataType: 'JSON',
128
+ data: data,
129
+ error: function( jqXHR, textStatus, errorThrown ) {
130
  $bucketList.html( '' );
131
  that.showError( as3cf.strings.get_buckets_error, errorThrown, 'as3cf-bucket-select' );
132
  },
133
+ success: function( data, textStatus, jqXHR ) {
134
  $bucketList.html( '' );
135
 
136
+ if ( 'undefined' !== typeof data[ 'success' ] ) {
137
  $( '.as3cf-bucket-error' ).hide();
138
 
139
  $( data[ 'buckets' ] ).each( function( idx, bucket ) {
177
  $bucketContainer.find( '.as3cf-bucket-select' ).show().siblings().hide();
178
  $bucketContainer.find( '.bucket-actions.select' ).show().siblings( '.bucket-actions' ).hide();
179
 
180
+ this.loadList( refreshBucketListOnLoad );
181
+
182
+ refreshBucketListOnLoad = false;
183
  }
184
 
185
  $bucketContainer.find( '.as3cf-bucket-error' ).hide();
213
  $manualBucketButton.prop( 'disabled', true );
214
 
215
  var data = {
216
+ action: as3cfModal.prefix + '-manual-save-bucket',
217
  bucket_name: bucketName,
218
+ _nonce: window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.manual_bucket
219
  };
220
 
221
  var that = this;
222
 
223
  $.ajax( {
224
+ url: ajaxurl,
225
+ type: 'POST',
226
  dataType: 'JSON',
227
+ data: data,
228
+ error: function( jqXHR, textStatus, errorThrown ) {
229
  $manualBucketButton.text( originalBucketText );
230
  that.showError( as3cf.strings.save_bucket_error, errorThrown, 'as3cf-bucket-manual' );
231
  },
232
+ success: function( data, textStatus, jqXHR ) {
233
  $manualBucketButton.text( originalBucketText );
234
  $manualBucketButton.prop( 'disabled', false );
235
+ if ( 'undefined' !== typeof data[ 'success' ] ) {
236
  that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
237
  $( '#' + as3cfModal.prefix + '-bucket-select' ).val( 'manual' );
238
  $( '.as3cf-bucket-list a' ).removeClass( 'selected' ).filter( '[data-bucket="' + bucketName + '"]' ).addClass( 'selected' );
239
+
240
+ // Make sure the bucket list will refresh the next time the modal loads
241
+ refreshBucketListOnLoad = true;
242
  } else {
243
  that.showError( as3cf.strings.save_bucket_error, data[ 'error' ], 'as3cf-bucket-manual' );
244
  }
255
  var $bucketList = $( '.as3cf-bucket-list' );
256
 
257
  if ( this.bucketSelectLock ) {
258
+
259
  // Bail if a bucket has already been clicked
260
  return;
261
  }
279
  var bucketName = $link.attr( 'data-bucket' );
280
 
281
  var data = {
282
+ action: as3cfModal.prefix + '-save-bucket',
283
  bucket_name: bucketName,
284
+ _nonce: window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.save_bucket
285
  };
286
 
287
  var that = this;
288
 
289
  $.ajax( {
290
+ url: ajaxurl,
291
+ type: 'POST',
292
  dataType: 'JSON',
293
+ data: data,
294
+ error: function( jqXHR, textStatus, errorThrown ) {
295
  $bucketList.removeClass( 'saving' );
296
  that.showError( as3cf.strings.save_bucket_error, errorThrown, 'as3cf-bucket-select' );
297
  $( '.as3cf-bucket-list a' ).removeClass( 'selected' );
298
  $( '.as3cf-bucket-list a[data-bucket="' + previousBucket + '"]' ).addClass( 'selected' );
299
  },
300
+ success: function( data, textStatus, jqXHR ) {
301
  $link.find( '.spinner' ).hide().css( 'visibility', 'hidden' );
302
  $bucketList.removeClass( 'saving' );
303
+ if ( 'undefined' !== typeof data[ 'success' ] ) {
304
  that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
305
  $( '#' + as3cfModal.prefix + '-bucket-select' ).val( '' );
306
  } else {
325
 
326
  if ( $createBucketForm.find( '.as3cf-bucket-name' ).val().length < 3 ) {
327
  $createBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
328
+ } else {
 
329
  $createBucketForm.find( 'button[type=submit]' ).attr( 'disabled', false );
330
  }
331
 
332
  if ( $manualBucketForm.find( '.as3cf-bucket-name' ).val().length < 3 ) {
333
  $manualBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
334
+ } else {
 
335
  $manualBucketForm.find( 'button[type=submit]' ).attr( 'disabled', false );
336
  }
337
  },
347
  var $activeView = $( '.as3cf-bucket-container' ).children( ':visible' );
348
  var $bucketError = $activeView.find( '.as3cf-bucket-error' );
349
 
350
+ context = ( 'undefined' === typeof context ) ? null : context;
351
 
352
  if ( context && ! $activeView.hasClass( context ) ) {
353
  return;
373
  var $activeBucket = $( '#' + as3cfModal.prefix + '-active-bucket' );
374
 
375
  if ( 'as3cf' === as3cfModal.prefix && 0 === $activeBucket.text().trim().length ) {
376
+
377
+ // First time bucket select - enable main options by default
378
  setCheckbox( 'copy-to-s3-wrap' );
379
  setCheckbox( 'serve-from-s3-wrap' );
380
 
381
+ // Update the saved settings string so we don't trigger the navigation alert
382
  var id = $activeTab.attr( 'id' );
383
  savedSettings[ id ] = serializedForm( id );
384
  }
393
  $( '.updated' ).not( '.as3cf-notice' ).show();
394
 
395
  $activeTab.addClass( 'as3cf-has-bucket' );
396
+
397
+ // Check permission on bucket
398
  $activeTab.find( '.as3cf-can-write-error' ).toggle( ! canWrite );
399
  $activeTab.find( '.as3cf-bucket-error' ).hide();
400
 
424
  $createBucketButton.prop( 'disabled', true );
425
 
426
  var data = {
427
+ action: as3cfModal.prefix + '-create-bucket',
428
  bucket_name: bucketName,
429
+ _nonce: window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.create_bucket
430
  };
431
 
432
  if ( $createBucketSelect.val() ) {
436
  var that = this;
437
 
438
  $.ajax( {
439
+ url: ajaxurl,
440
+ type: 'POST',
441
  dataType: 'JSON',
442
+ data: data,
443
+ error: function( jqXHR, textStatus, errorThrown ) {
444
  $createBucketButton.text( origButtonText );
445
  that.showError( as3cf.strings.create_bucket_error, errorThrown, 'as3cf-bucket-create' );
446
  },
447
+ success: function( data, textStatus, jqXHR ) {
448
  $createBucketButton.text( origButtonText );
449
  $createBucketButton.prop( 'disabled', false );
450
+ if ( 'undefined' !== typeof data[ 'success' ] ) {
451
  that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
452
+
453
+ // Tidy up create bucket form
454
  $( '.as3cf-bucket-select-region' ).hide();
455
  $( '.as3cf-bucket-select-region' ).removeAttr( 'selected' );
456
  $createBucketInput.val( '' );
457
  $createBucketButton.attr( 'disabled', true );
458
+
459
+ // Make sure the bucket list will refresh the next time the modal loads
460
+ refreshBucketListOnLoad = true;
461
  } else {
462
  that.showError( as3cf.strings.create_bucket_error, data[ 'error' ], 'as3cf-bucket-create' );
463
  }
544
  var n = o.name,
545
  v = o.value;
546
  n = n.replace( '[]', '' );
547
+ data[ n ] = undefined === data[ n ] ? v : $.isArray( data[ n ] ) ? data[ n ].concat( v ) : [ data[ n ], v ];
548
  } );
549
 
550
+ // Overwrite the save action stored in the form
551
  data[ 'action' ] = 'as3cf-get-url-preview';
552
 
553
  $.ajax( {
559
  alert( as3cf.strings.get_url_preview_error + errorThrown );
560
  },
561
  success: function( data, textStatus, jqXHR ) {
562
+ if ( 'undefined' !== typeof data[ 'success' ] ) {
563
  $( '.as3cf-url-preview' ).html( data[ 'url' ] );
564
  } else {
565
  alert( as3cf.strings.get_url_preview_error + data[ 'error' ] );
572
  * Reset the bucket select lock
573
  */
574
  function unlockBucketSelect( target ) {
575
+
576
  // Unlock setting the bucket
577
  as3cf.buckets.bucketSelectLock = false;
578
  }
608
  var $navTabs = $( '.wrap.aws-main .nav-tab-wrapper' );
609
  $( '.aws-compatibility-notice, div.updated, div.error, div.notice' ).not( '.below-h2, .inline' ).insertAfter( $navTabs );
610
 
611
+ // Check for hash in url and switch tabs accordingly
612
  if ( window.location.hash ) {
613
  var hash = window.location.hash.substring( 1 );
614
  as3cf.tabs.toggle( hash, true );
615
  } else {
616
+
617
+ // Default settings tab
618
  $activeTab = $( '#tab-' + as3cf.tabs.defaultTab );
619
  $( '.aws-main' ).attr( 'data-tab', as3cf.tabs.defaultTab );
620
  }
627
  var nextTab = $( this ).attr( 'data-tab' );
628
  as3cf.tabs.toggle( nextTab );
629
  if ( 'media' === nextTab ) {
630
+
631
  // As it's the default remove the hash
632
  window.location.hash = '';
633
+ if ( 'function' === typeof window.history.replaceState && '#' === window.location.href.slice( -1 ) ) {
634
+
635
  // Strip the # if still on the end of the URL
636
  history.replaceState( {}, '', window.location.href.slice( 0, -1 ) );
637
  }
643
  // Settings
644
  // --------------------
645
 
646
+ // Save the original state of the forms for comparison later
647
  if ( $tabs.length ) {
648
  $tabs.each( function( i, tab ) {
649
  savedSettings[ tab.id ] = serializedForm( tab.id );
650
  } );
651
  }
652
 
653
+ // Prompt user with dialog if leaving the settings page with unsaved changes
654
  $( window ).on( 'beforeunload.as3cf-settings', function() {
655
  if ( $.isEmptyObject( savedSettings ) ) {
656
  return;
663
  }
664
  } );
665
 
666
+ // Let the save settings submit happen as normal
667
  $( document ).on( 'submit', '.as3cf-main-settings form', function( e ) {
668
+
669
+ // Disable unload warning
670
  $( window ).off( 'beforeunload.as3cf-settings' );
671
  } );
672
 
673
  $( '.as3cf-switch' ).on( 'click', function( e ) {
674
+ if ( ! $( this ).hasClass( 'disabled' ) ) {
675
  setCheckbox( $( this ).attr( 'id' ) );
676
  }
677
  } );
686
  var domain = $selected.val();
687
  var $cloudfront = $( this ).parents( '.as3cf-domain' ).find( '.as3cf-setting.cloudfront' );
688
  var cloudfrontSelected = ( 'cloudfront' === domain );
689
+ $cloudfront.toggleClass( 'hide', ! cloudfrontSelected );
690
  } );
691
 
692
  $( '.as3cf-ssl' ).on( 'change', 'input[type="radio"]', function( e ) {
693
+ if ( ! $( '#' + $activeTab.attr( 'id' ) + ' .deprecated-domain' ).length ) {
694
+ return;
695
+ }
696
+
697
  var ssl = $( 'input:radio[name="ssl"]:checked' ).val();
698
  if ( 'https' === ssl ) {
699
  var domain = $( 'input:radio[name="domain"]:checked' ).val();
700
  if ( 'subdomain' === domain ) {
701
+ $( 'input[name="domain"][value="path"]' ).attr( 'checked', true );
702
  }
703
  $( '.subdomain-wrap input' ).attr( 'disabled', true );
704
  $( '.subdomain-wrap' ).addClass( 'disabled' );
729
 
730
  return false;
731
  }
 
732
  } );
733
 
734
  // Validate custom domain
767
  $( 'body' ).on( 'click', '.bucket-action-browse', function( e ) {
768
  e.preventDefault();
769
  $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-bucket-select' ).show().siblings().hide();
770
+ as3cf.buckets.loadList( refreshBucketListOnLoad );
771
+ refreshBucketListOnLoad = false;
772
  } );
773
  $( 'body' ).on( 'click', '.bucket-action-create', function( e ) {
774
  e.preventDefault();
815
  // Modal open
816
  $( 'body' ).on( 'as3cf-modal-open', function( e, target ) {
817
  if ( '.as3cf-bucket-container.' + as3cfModal.prefix === target ) {
818
+
819
  // Reset modal
820
  as3cf.buckets.resetModal();
821
+
822
  // Change manual title text
823
  var title = $( '.as3cf-bucket-manual h3' ).data( 'modal-title' );
824
  $( '.as3cf-bucket-manual h3' ).text( title );
825
+
826
  // Hide buttons
827
  as3cf.buckets.disabledButtons();
828
  }
assets/js/script.min.js CHANGED
@@ -1 +1 @@
1
- !function(a,b){function c(b){return a("#"+b+" .as3cf-main-settings form").find("input:not(.no-compare)").serialize()}function d(b){var c=a("#"+b),d=c.find("input[type=checkbox]");c.toggleClass("on").find("span").toggleClass("checked");var e=c.find("span.on").hasClass("checked");d.attr("checked",e).trigger("change")}function e(b){var c=b.next(".as3cf-validation-error"),d=a("#"+k.attr("id")+' form button[type="submit"]'),e=/[^a-zA-Z0-9\.\-]/;e.test(b.val())?(c.show(),d.attr("disabled",!0)):(c.hide(),d.attr("disabled",!1))}function f(){var c=a("#"+b.prefix+"-bucket").val(),d=k.find('input[name="object-prefix"]'),e=d.val();""!==e&&(e="&prefix="+encodeURIComponent(e));var f=as3cf.aws_bucket_link+c+e;a("#"+b.prefix+"-view-bucket").attr("href",f)}function g(){a(".as3cf-url-preview").html("Generating...");var b={_nonce:as3cf.nonces.get_url_preview};a.each(a("#tab-"+as3cf.tabs.defaultTab+" .as3cf-main-settings form").serializeArray(),function(c,d){var e=d.name,f=d.value;e=e.replace("[]",""),b[e]=void 0===b[e]?f:a.isArray(b[e])?b[e].concat(f):[b[e],f]}),b.action="as3cf-get-url-preview",a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:b,error:function(a,b,c){alert(as3cf.strings.get_url_preview_error+c)},success:function(b,c,d){"undefined"!=typeof b.success?a(".as3cf-url-preview").html(b.url):alert(as3cf.strings.get_url_preview_error+b.error)}})}function h(a){as3cf.buckets.bucketSelectLock=!1}function i(){a("#remove-local-file").is(":checked")&&a("#serve-from-s3").is(":not(:checked)")?a("#as3cf-lost-files-notice").show():a("#as3cf-lost-files-notice").hide()}function j(){a("#remove-local-file").is(":checked")?a("#as3cf-remove-local-notice").show():a("#as3cf-remove-local-notice").hide()}var k,l={},m=/[^a-z0-9.-]/,n=a(".as3cf-tab");as3cf.tabs={defaultTab:"media",toggle:function(c,d){n.hide(),k=a("#tab-"+c),k.show(),a(".nav-tab").removeClass("nav-tab-active"),a('a.nav-tab[data-tab="'+c+'"]').addClass("nav-tab-active"),a(".aws-main").attr("data-tab",c),k.attr("data-prefix")&&(b.prefix=k.attr("data-prefix")),d||a(".as3cf-updated").removeClass("show")}},as3cf.buckets={validLength:3,bucketSelectLock:!1,loadList:function(c){"undefined"==typeof c&&(c=!1);var d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-list"),e=a("#"+b.prefix+"-bucket").val();if(!1===c&&d.find("li").length>1)return a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected"),void this.scrollToSelected();d.html('<li class="loading">'+d.attr("data-working")+"</li>");var f={action:b.prefix+"-get-buckets",_nonce:window[b.prefix.replace(/-/g,"_")].nonces.get_buckets},g=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:f,error:function(a,b,c){d.html(""),g.showError(as3cf.strings.get_buckets_error,c,"as3cf-bucket-select")},success:function(b,c,f){d.html(""),"undefined"!=typeof b.success?(a(".as3cf-bucket-error").hide(),a(b.buckets).each(function(a,b){var c=b.Name===e?"selected":"";d.append('<li><a class="'+c+'" href="#" data-bucket="'+b.Name+'"><span class="bucket"><span class="dashicons dashicons-portfolio"></span> '+b.Name+'</span><span class="spinner"></span></span></a></li>')}),g.scrollToSelected()):g.showError(as3cf.strings.get_buckets_error,b.error,"as3cf-bucket-select")}})},scrollToSelected:function(){if(a(".as3cf-bucket-list a.selected").length){var b=a("ul.as3cf-bucket-list li").first().position().top+150;a(".as3cf-bucket-list").animate({scrollTop:a("ul.as3cf-bucket-list li a.selected").position().top-b})}},resetModal:function(){var c=a(".as3cf-bucket-container."+b.prefix);!1===k.hasClass("as3cf-has-bucket")||"manual"===a("#"+b.prefix+"-bucket-select").val()?(c.find(".as3cf-bucket-manual").show().siblings().hide(),c.find(".bucket-actions.manual").show().siblings(".bucket-actions").hide()):(c.find(".as3cf-bucket-select").show().siblings().hide(),c.find(".bucket-actions.select").show().siblings(".bucket-actions").hide(),this.loadList()),c.find(".as3cf-bucket-error").hide();var d=a("#"+b.prefix+"-bucket").val();c.find(".as3cf-bucket-manual .as3cf-bucket-name").val(d),this.bucketSelectLock=!1},saveManual:function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),d=c.find(".as3cf-bucket-name"),e=c.find("button[type=submit]"),f=d.val(),g=e.first().text();if(f===a("#"+b.prefix+"-active-bucket").text())return a(".as3cf-bucket-error").hide(),k.addClass("as3cf-has-bucket"),void b.close();a(".as3cf-bucket-error").hide(),e.text(e.attr("data-working")),e.prop("disabled",!0);var h={action:b.prefix+"-manual-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.manual_bucket},i=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:h,error:function(a,b,c){e.text(g),i.showError(as3cf.strings.save_bucket_error,c,"as3cf-bucket-manual")},success:function(c,d,h){e.text(g),e.prop("disabled",!1),"undefined"!=typeof c.success?(i.set(f,c.region,c.can_write),a("#"+b.prefix+"-bucket-select").val("manual"),a(".as3cf-bucket-list a").removeClass("selected").filter('[data-bucket="'+f+'"]').addClass("selected")):i.showError(as3cf.strings.save_bucket_error,c.error,"as3cf-bucket-manual")}})},saveSelected:function(c){var d=a(".as3cf-bucket-list");if(!this.bucketSelectLock){if(this.bucketSelectLock=!0,c.hasClass("selected"))return k.addClass("as3cf-has-bucket"),void b.close();var e=a(".as3cf-bucket-list a.selected").attr("data-bucket");a(".as3cf-bucket-list a").removeClass("selected"),c.addClass("selected"),d.addClass("saving"),c.find(".spinner").show().css("visibility","visible");var f=c.attr("data-bucket"),g={action:b.prefix+"-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.save_bucket},h=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:g,error:function(b,c,f){d.removeClass("saving"),h.showError(as3cf.strings.save_bucket_error,f,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected")},success:function(g,i,j){c.find(".spinner").hide().css("visibility","hidden"),d.removeClass("saving"),"undefined"!=typeof g.success?(h.set(f,g.region,g.can_write),a("#"+b.prefix+"-bucket-select").val("")):(h.showError(as3cf.strings.save_bucket_error,g.error,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected"))}})}},disabledButtons:function(){if(0!==a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form").length){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form"),d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");c.find(".as3cf-bucket-name").val().length<3?c.find("button[type=submit]").attr("disabled",!0):c.find("button[type=submit]").attr("disabled",!1),d.find(".as3cf-bucket-name").val().length<3?d.find("button[type=submit]").attr("disabled",!0):d.find("button[type=submit]").attr("disabled",!1)}},showError:function(b,c,d){var e=a(".as3cf-bucket-container").children(":visible"),f=e.find(".as3cf-bucket-error");d="undefined"==typeof d?null:d,(!d||e.hasClass(d))&&(f.find("span.title").html(b+" &mdash;"),f.find("span.message").html(c),f.show(),this.bucketSelectLock=!1)},set:function(e,i,j){var m=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),n=a("#"+b.prefix+"-active-bucket");if("as3cf"===b.prefix&&0===n.text().trim().length){d("copy-to-s3-wrap"),d("serve-from-s3-wrap");var o=k.attr("id");l[o]=c(o)}a(".as3cf-error.fatal").hide(),n.text(e),m.find(".as3cf-bucket-name").val(e),a("#"+b.prefix+"-bucket").val(e),a("#"+b.prefix+"-region").val(i),a(".updated").not(".as3cf-notice").show(),k.addClass("as3cf-has-bucket"),k.find(".as3cf-can-write-error").toggle(!j),k.find(".as3cf-bucket-error").hide(),"as3cf"===b.prefix&&g(),f(),b.close(h)},create:function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form"),d=c.find(".as3cf-bucket-name"),e=c.find(".bucket-create-region"),f=c.find("button[type=submit]"),g=d.val(),h=f.text();a(".as3cf-bucket-error").hide(),f.text(f.attr("data-working")),f.prop("disabled",!0);var i={action:b.prefix+"-create-bucket",bucket_name:g,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.create_bucket};e.val()&&(i.region=e.val());var j=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:i,error:function(a,b,c){f.text(h),j.showError(as3cf.strings.create_bucket_error,c,"as3cf-bucket-create")},success:function(b,c,e){f.text(h),f.prop("disabled",!1),"undefined"!=typeof b.success?(j.set(g,b.region,b.can_write),a(".as3cf-bucket-select-region").hide(),a(".as3cf-bucket-select-region").removeAttr("selected"),d.val(""),f.attr("disabled",!0)):j.showError(as3cf.strings.create_bucket_error,b.error,"as3cf-bucket-create")}})},isValidName:function(a){return a.length<3||a.length>63?!1:!0===m.test(a)?!1:!0},updateNameNotice:function(b){var c=null;!0===m.test(b)?c=as3cf.strings.create_bucket_invalid_chars:b.length<3?c=as3cf.strings.create_bucket_name_short:b.length>63&&(c=as3cf.strings.create_bucket_name_long),c&&b.length>0?a(".as3cf-invalid-bucket-name").html(c):a(".as3cf-invalid-bucket-name").html("")}},a(document).ready(function(){var h=a(".wrap.aws-main .nav-tab-wrapper");if(a(".aws-compatibility-notice, div.updated, div.error, div.notice").not(".below-h2, .inline").insertAfter(h),window.location.hash){var m=window.location.hash.substring(1);as3cf.tabs.toggle(m,!0)}else k=a("#tab-"+as3cf.tabs.defaultTab),a(".aws-main").attr("data-tab",as3cf.tabs.defaultTab);a(".aws-main").on("click",".nav-tab",function(b){if(b.preventDefault(),!a(this).hasClass("nav-tab-active")){var c=a(this).attr("data-tab");as3cf.tabs.toggle(c),"media"===c?(window.location.hash="","function"==typeof window.history.replaceState&&"#"===window.location.href.slice(-1)&&history.replaceState({},"",window.location.href.slice(0,-1))):window.location.hash=c}}),n.length&&n.each(function(a,b){l[b.id]=c(b.id)}),a(window).on("beforeunload.as3cf-settings",function(){if(!a.isEmptyObject(l)){var b=k.attr("id");return c(b)!==l[b]?as3cf.strings.save_alert:void 0}}),a(document).on("submit",".as3cf-main-settings form",function(b){a(window).off("beforeunload.as3cf-settings")}),a(".as3cf-switch").on("click",function(b){a(this).hasClass("disabled")||d(a(this).attr("id"))}),n.on("change",".sub-toggle",function(b){var c=a(this).attr("id");a(".as3cf-setting."+c).toggleClass("hide")}),a(".as3cf-domain").on("change",'input[type="radio"]',function(b){var c=a(this).closest('input:radio[name="domain"]:checked'),d=c.val(),e=a(this).parents(".as3cf-domain").find(".as3cf-setting.cloudfront"),f="cloudfront"===d;e.toggleClass("hide",!f)}),a(".as3cf-ssl").on("change",'input[type="radio"]',function(b){var c=a('input:radio[name="ssl"]:checked').val();if("https"===c){var d=a('input:radio[name="domain"]:checked').val();"subdomain"===d&&a('input[name="domain"][value="path"]').attr("checked",!0),a(".subdomain-wrap input").attr("disabled",!0),a(".subdomain-wrap").addClass("disabled")}else a(".subdomain-wrap input").removeAttr("disabled"),a(".subdomain-wrap").removeClass("disabled")}),a(".url-preview").on("change","input",function(a){g()}),i(),a("#serve-from-s3,#remove-local-file").on("change",function(a){i()}),j(),a("#remove-local-file").on("change",function(a){j()}),a('.as3cf-setting input[type="text"]').keypress(function(a){return 13===a.which?(a.preventDefault(),!1):void 0}),a('input[name="cloudfront"]').on("keyup",function(b){e(a(this))}),a('input[name="domain"]').on("change",function(b){var c=a(this),d=a("#"+k.attr("id")+' form button[type="submit"]');"cloudfront"!==c.val()?d.attr("disabled",!1):e(c.next(".as3cf-setting").find('input[name="cloudfront"]'))}),a('input[name="object-prefix"]').on("change",function(a){f()}),a("#tab-media > .as3cf-bucket-error").detach().insertAfter(".as3cf-bucket-container h3"),a("body").on("click",".bucket-action-manual",function(c){c.preventDefault(),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-manual").show().siblings().hide()}),a("body").on("click",".bucket-action-browse",function(c){c.preventDefault(),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-select").show().siblings().hide(),as3cf.buckets.loadList()}),a("body").on("click",".bucket-action-create",function(c){c.preventDefault(),a(".as3cf-bucket-name").val(""),a(".as3cf-invalid-bucket-name").html(""),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-create").show().siblings().hide()}),a("body").on("click",".bucket-action-cancel",function(a){a.preventDefault(),as3cf.buckets.resetModal()}),a("body").on("click",".bucket-action-save",function(a){a.preventDefault(),as3cf.buckets.saveManual()}),a("body").on("click",'.as3cf-create-bucket-form button[type="submit"]',function(a){a.preventDefault(),as3cf.buckets.create()}),a("body").on("click",".bucket-action-refresh",function(a){a.preventDefault(),as3cf.buckets.loadList(!0)}),a("body").on("click",".as3cf-bucket-list a",function(b){b.preventDefault(),as3cf.buckets.saveSelected(a(this))}),a(".as3cf-bucket-container").on("click","a.js-link",function(b){return b.preventDefault(),window.open(a(this).attr("href")),!1}),a("body").on("as3cf-modal-open",function(c,d){if(".as3cf-bucket-container."+b.prefix===d){as3cf.buckets.resetModal();var e=a(".as3cf-bucket-manual h3").data("modal-title");a(".as3cf-bucket-manual h3").text(e),as3cf.buckets.disabledButtons()}}),as3cf.buckets.disabledButtons(),a("body").on("input keyup",".as3cf-create-bucket-form .as3cf-bucket-name",function(c){var d=a(this).val(),e=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form");as3cf.buckets.isValidName(d)?e.find("button[type=submit]").removeAttr("disabled"):e.find("button[type=submit]").attr("disabled",!0),as3cf.buckets.updateNameNotice(d)}),a("body").on("input keyup",".as3cf-manual-save-bucket-form .as3cf-bucket-name",function(c){var d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");d.find(".as3cf-bucket-name").val().length<as3cf.buckets.validLength?d.find("button[type=submit]").attr("disabled",!0):d.find("button[type=submit]").removeAttr("disabled")})})}(jQuery,as3cfModal);
1
+ !function(a,b){function c(b){return a("#"+b+" .as3cf-main-settings form").find("input:not(.no-compare)").serialize()}function d(a){var b=k.find("#"+a),c=b.find("input[type=checkbox]");b.toggleClass("on").find("span").toggleClass("checked");var d=b.find("span.on").hasClass("checked");c.attr("checked",d).trigger("change")}function e(b){var c=b.next(".as3cf-validation-error"),d=a("#"+k.attr("id")+' form button[type="submit"]'),e=/[^a-zA-Z0-9\.\-]/;e.test(b.val())?(c.show(),d.attr("disabled",!0)):(c.hide(),d.attr("disabled",!1))}function f(){var c=a("#"+b.prefix+"-bucket").val(),d=k.find('input[name="object-prefix"]'),e=d.val();""!==e&&(e="&prefix="+encodeURIComponent(e));var f=as3cf.aws_bucket_link+c+e;a("#"+b.prefix+"-view-bucket").attr("href",f)}function g(){a(".as3cf-url-preview").html("Generating...");var b={_nonce:as3cf.nonces.get_url_preview};a.each(a("#tab-"+as3cf.tabs.defaultTab+" .as3cf-main-settings form").serializeArray(),function(c,d){var e=d.name,f=d.value;e=e.replace("[]",""),b[e]=void 0===b[e]?f:a.isArray(b[e])?b[e].concat(f):[b[e],f]}),b.action="as3cf-get-url-preview",a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:b,error:function(a,b,c){alert(as3cf.strings.get_url_preview_error+c)},success:function(b,c,d){"undefined"!=typeof b.success?a(".as3cf-url-preview").html(b.url):alert(as3cf.strings.get_url_preview_error+b.error)}})}function h(a){as3cf.buckets.bucketSelectLock=!1}function i(){a("#remove-local-file").is(":checked")&&a("#serve-from-s3").is(":not(:checked)")?a("#as3cf-lost-files-notice").show():a("#as3cf-lost-files-notice").hide()}function j(){a("#remove-local-file").is(":checked")?a("#as3cf-remove-local-notice").show():a("#as3cf-remove-local-notice").hide()}var k,l={},m=/[^a-z0-9.-]/,n=!1,o=a(".as3cf-tab");as3cf.tabs={defaultTab:"media",toggle:function(c,d){o.hide(),k=a("#tab-"+c),k.show(),a(".nav-tab").removeClass("nav-tab-active"),a('a.nav-tab[data-tab="'+c+'"]').addClass("nav-tab-active"),a(".aws-main").attr("data-tab",c),k.attr("data-prefix")&&(b.prefix=k.attr("data-prefix")),d||a(".as3cf-updated").removeClass("show")}},as3cf.buckets={validLength:3,bucketSelectLock:!1,loadList:function(c){"undefined"==typeof c&&(c=!1);var d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-list"),e=a("#"+b.prefix+"-bucket").val();if(!1===c&&d.find("li").length>1)return a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected"),void this.scrollToSelected();d.html('<li class="loading">'+d.attr("data-working")+"</li>");var f={action:b.prefix+"-get-buckets",_nonce:window[b.prefix.replace(/-/g,"_")].nonces.get_buckets},g=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:f,error:function(a,b,c){d.html(""),g.showError(as3cf.strings.get_buckets_error,c,"as3cf-bucket-select")},success:function(b,c,f){d.html(""),"undefined"!=typeof b.success?(a(".as3cf-bucket-error").hide(),a(b.buckets).each(function(a,b){var c=b.Name===e?"selected":"";d.append('<li><a class="'+c+'" href="#" data-bucket="'+b.Name+'"><span class="bucket"><span class="dashicons dashicons-portfolio"></span> '+b.Name+'</span><span class="spinner"></span></span></a></li>')}),g.scrollToSelected()):g.showError(as3cf.strings.get_buckets_error,b.error,"as3cf-bucket-select")}})},scrollToSelected:function(){if(a(".as3cf-bucket-list a.selected").length){var b=a("ul.as3cf-bucket-list li").first().position().top+150;a(".as3cf-bucket-list").animate({scrollTop:a("ul.as3cf-bucket-list li a.selected").position().top-b})}},resetModal:function(){var c=a(".as3cf-bucket-container."+b.prefix);!1===k.hasClass("as3cf-has-bucket")||"manual"===a("#"+b.prefix+"-bucket-select").val()?(c.find(".as3cf-bucket-manual").show().siblings().hide(),c.find(".bucket-actions.manual").show().siblings(".bucket-actions").hide()):(c.find(".as3cf-bucket-select").show().siblings().hide(),c.find(".bucket-actions.select").show().siblings(".bucket-actions").hide(),this.loadList(n),n=!1),c.find(".as3cf-bucket-error").hide();var d=a("#"+b.prefix+"-bucket").val();c.find(".as3cf-bucket-manual .as3cf-bucket-name").val(d),this.bucketSelectLock=!1},saveManual:function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),d=c.find(".as3cf-bucket-name"),e=c.find("button[type=submit]"),f=d.val(),g=e.first().text();if(f===a("#"+b.prefix+"-active-bucket").text())return a(".as3cf-bucket-error").hide(),k.addClass("as3cf-has-bucket"),void b.close();a(".as3cf-bucket-error").hide(),e.text(e.attr("data-working")),e.prop("disabled",!0);var h={action:b.prefix+"-manual-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.manual_bucket},i=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:h,error:function(a,b,c){e.text(g),i.showError(as3cf.strings.save_bucket_error,c,"as3cf-bucket-manual")},success:function(c,d,h){e.text(g),e.prop("disabled",!1),"undefined"!=typeof c.success?(i.set(f,c.region,c.can_write),a("#"+b.prefix+"-bucket-select").val("manual"),a(".as3cf-bucket-list a").removeClass("selected").filter('[data-bucket="'+f+'"]').addClass("selected"),n=!0):i.showError(as3cf.strings.save_bucket_error,c.error,"as3cf-bucket-manual")}})},saveSelected:function(c){var d=a(".as3cf-bucket-list");if(!this.bucketSelectLock){if(this.bucketSelectLock=!0,c.hasClass("selected"))return k.addClass("as3cf-has-bucket"),void b.close();var e=a(".as3cf-bucket-list a.selected").attr("data-bucket");a(".as3cf-bucket-list a").removeClass("selected"),c.addClass("selected"),d.addClass("saving"),c.find(".spinner").show().css("visibility","visible");var f=c.attr("data-bucket"),g={action:b.prefix+"-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.save_bucket},h=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:g,error:function(b,c,f){d.removeClass("saving"),h.showError(as3cf.strings.save_bucket_error,f,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected")},success:function(g,i,j){c.find(".spinner").hide().css("visibility","hidden"),d.removeClass("saving"),"undefined"!=typeof g.success?(h.set(f,g.region,g.can_write),a("#"+b.prefix+"-bucket-select").val("")):(h.showError(as3cf.strings.save_bucket_error,g.error,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected"))}})}},disabledButtons:function(){if(0!==a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form").length){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form"),d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");c.find(".as3cf-bucket-name").val().length<3?c.find("button[type=submit]").attr("disabled",!0):c.find("button[type=submit]").attr("disabled",!1),d.find(".as3cf-bucket-name").val().length<3?d.find("button[type=submit]").attr("disabled",!0):d.find("button[type=submit]").attr("disabled",!1)}},showError:function(b,c,d){var e=a(".as3cf-bucket-container").children(":visible"),f=e.find(".as3cf-bucket-error");d="undefined"==typeof d?null:d,d&&!e.hasClass(d)||(f.find("span.title").html(b+" &mdash;"),f.find("span.message").html(c),f.show(),this.bucketSelectLock=!1)},set:function(e,i,j){var m=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),n=a("#"+b.prefix+"-active-bucket");if("as3cf"===b.prefix&&0===n.text().trim().length){d("copy-to-s3-wrap"),d("serve-from-s3-wrap");var o=k.attr("id");l[o]=c(o)}a(".as3cf-error.fatal").hide(),n.text(e),m.find(".as3cf-bucket-name").val(e),a("#"+b.prefix+"-bucket").val(e),a("#"+b.prefix+"-region").val(i),a(".updated").not(".as3cf-notice").show(),k.addClass("as3cf-has-bucket"),k.find(".as3cf-can-write-error").toggle(!j),k.find(".as3cf-bucket-error").hide(),"as3cf"===b.prefix&&g(),f(),b.close(h)},create:function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form"),d=c.find(".as3cf-bucket-name"),e=c.find(".bucket-create-region"),f=c.find("button[type=submit]"),g=d.val(),h=f.text();a(".as3cf-bucket-error").hide(),f.text(f.attr("data-working")),f.prop("disabled",!0);var i={action:b.prefix+"-create-bucket",bucket_name:g,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.create_bucket};e.val()&&(i.region=e.val());var j=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:i,error:function(a,b,c){f.text(h),j.showError(as3cf.strings.create_bucket_error,c,"as3cf-bucket-create")},success:function(b,c,e){f.text(h),f.prop("disabled",!1),"undefined"!=typeof b.success?(j.set(g,b.region,b.can_write),a(".as3cf-bucket-select-region").hide(),a(".as3cf-bucket-select-region").removeAttr("selected"),d.val(""),f.attr("disabled",!0),n=!0):j.showError(as3cf.strings.create_bucket_error,b.error,"as3cf-bucket-create")}})},isValidName:function(a){return a.length<3||a.length>63?!1:!0!==m.test(a)},updateNameNotice:function(b){var c=null;!0===m.test(b)?c=as3cf.strings.create_bucket_invalid_chars:b.length<3?c=as3cf.strings.create_bucket_name_short:b.length>63&&(c=as3cf.strings.create_bucket_name_long),c&&b.length>0?a(".as3cf-invalid-bucket-name").html(c):a(".as3cf-invalid-bucket-name").html("")}},a(document).ready(function(){var h=a(".wrap.aws-main .nav-tab-wrapper");if(a(".aws-compatibility-notice, div.updated, div.error, div.notice").not(".below-h2, .inline").insertAfter(h),window.location.hash){var m=window.location.hash.substring(1);as3cf.tabs.toggle(m,!0)}else k=a("#tab-"+as3cf.tabs.defaultTab),a(".aws-main").attr("data-tab",as3cf.tabs.defaultTab);a(".aws-main").on("click",".nav-tab",function(b){if(b.preventDefault(),!a(this).hasClass("nav-tab-active")){var c=a(this).attr("data-tab");as3cf.tabs.toggle(c),"media"===c?(window.location.hash="","function"==typeof window.history.replaceState&&"#"===window.location.href.slice(-1)&&history.replaceState({},"",window.location.href.slice(0,-1))):window.location.hash=c}}),o.length&&o.each(function(a,b){l[b.id]=c(b.id)}),a(window).on("beforeunload.as3cf-settings",function(){if(!a.isEmptyObject(l)){var b=k.attr("id");return c(b)!==l[b]?as3cf.strings.save_alert:void 0}}),a(document).on("submit",".as3cf-main-settings form",function(b){a(window).off("beforeunload.as3cf-settings")}),a(".as3cf-switch").on("click",function(b){a(this).hasClass("disabled")||d(a(this).attr("id"))}),o.on("change",".sub-toggle",function(b){var c=a(this).attr("id");a(".as3cf-setting."+c).toggleClass("hide")}),a(".as3cf-domain").on("change",'input[type="radio"]',function(b){var c=a(this).closest('input:radio[name="domain"]:checked'),d=c.val(),e=a(this).parents(".as3cf-domain").find(".as3cf-setting.cloudfront"),f="cloudfront"===d;e.toggleClass("hide",!f)}),a(".as3cf-ssl").on("change",'input[type="radio"]',function(b){if(a("#"+k.attr("id")+" .deprecated-domain").length){var c=a('input:radio[name="ssl"]:checked').val();if("https"===c){var d=a('input:radio[name="domain"]:checked').val();"subdomain"===d&&a('input[name="domain"][value="path"]').attr("checked",!0),a(".subdomain-wrap input").attr("disabled",!0),a(".subdomain-wrap").addClass("disabled")}else a(".subdomain-wrap input").removeAttr("disabled"),a(".subdomain-wrap").removeClass("disabled")}}),a(".url-preview").on("change","input",function(a){g()}),i(),a("#serve-from-s3,#remove-local-file").on("change",function(a){i()}),j(),a("#remove-local-file").on("change",function(a){j()}),a('.as3cf-setting input[type="text"]').keypress(function(a){return 13===a.which?(a.preventDefault(),!1):void 0}),a('input[name="cloudfront"]').on("keyup",function(b){e(a(this))}),a('input[name="domain"]').on("change",function(b){var c=a(this),d=a("#"+k.attr("id")+' form button[type="submit"]');"cloudfront"!==c.val()?d.attr("disabled",!1):e(c.next(".as3cf-setting").find('input[name="cloudfront"]'))}),a('input[name="object-prefix"]').on("change",function(a){f()}),a("#tab-media > .as3cf-bucket-error").detach().insertAfter(".as3cf-bucket-container h3"),a("body").on("click",".bucket-action-manual",function(c){c.preventDefault(),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-manual").show().siblings().hide()}),a("body").on("click",".bucket-action-browse",function(c){c.preventDefault(),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-select").show().siblings().hide(),as3cf.buckets.loadList(n),n=!1}),a("body").on("click",".bucket-action-create",function(c){c.preventDefault(),a(".as3cf-bucket-name").val(""),a(".as3cf-invalid-bucket-name").html(""),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-create").show().siblings().hide()}),a("body").on("click",".bucket-action-cancel",function(a){a.preventDefault(),as3cf.buckets.resetModal()}),a("body").on("click",".bucket-action-save",function(a){a.preventDefault(),as3cf.buckets.saveManual()}),a("body").on("click",'.as3cf-create-bucket-form button[type="submit"]',function(a){a.preventDefault(),as3cf.buckets.create()}),a("body").on("click",".bucket-action-refresh",function(a){a.preventDefault(),as3cf.buckets.loadList(!0)}),a("body").on("click",".as3cf-bucket-list a",function(b){b.preventDefault(),as3cf.buckets.saveSelected(a(this))}),a(".as3cf-bucket-container").on("click","a.js-link",function(b){return b.preventDefault(),window.open(a(this).attr("href")),!1}),a("body").on("as3cf-modal-open",function(c,d){if(".as3cf-bucket-container."+b.prefix===d){as3cf.buckets.resetModal();var e=a(".as3cf-bucket-manual h3").data("modal-title");a(".as3cf-bucket-manual h3").text(e),as3cf.buckets.disabledButtons()}}),as3cf.buckets.disabledButtons(),a("body").on("input keyup",".as3cf-create-bucket-form .as3cf-bucket-name",function(c){var d=a(this).val(),e=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form");as3cf.buckets.isValidName(d)?e.find("button[type=submit]").removeAttr("disabled"):e.find("button[type=submit]").attr("disabled",!0),as3cf.buckets.updateNameNotice(d)}),a("body").on("input keyup",".as3cf-manual-save-bucket-form .as3cf-bucket-name",function(c){var d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");d.find(".as3cf-bucket-name").val().length<as3cf.buckets.validLength?d.find("button[type=submit]").attr("disabled",!0):d.find("button[type=submit]").removeAttr("disabled")})})}(jQuery,as3cfModal);
assets/sass/styles.scss CHANGED
@@ -36,6 +36,10 @@
36
  }
37
  }
38
 
 
 
 
 
39
  .error {
40
  pre {
41
  background: #eaeaea;
@@ -142,12 +146,13 @@
142
  }
143
  }
144
 
145
- .as3cf-ssl {
146
- p.info {
147
- margin-top: 10px;
148
- padding: 0;
 
 
149
  }
150
- }
151
 
152
  .as3cf-radio-group {
153
  label {
@@ -267,6 +272,10 @@
267
  .as3cf-notice:last-child {
268
  margin-bottom: 0;
269
  }
 
 
 
 
270
  }
271
 
272
  &:first-of-type {
@@ -275,6 +284,11 @@
275
  }
276
  }
277
  }
 
 
 
 
 
278
  h3 {
279
  padding: 0;
280
  margin: 0;
@@ -295,6 +309,9 @@
295
  &:hover, &:active {
296
  color: #00a0d2;
297
  }
 
 
 
298
  .dashicons-external {
299
  margin-top: -2px;
300
  }
@@ -361,6 +378,34 @@
361
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
362
  opacity: 1;
363
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
  }
365
 
366
  /**
@@ -737,4 +782,16 @@
737
  margin-top: 2px;
738
  font-size: 12px;
739
  color: #a00;
 
 
 
 
 
 
 
 
 
 
 
 
740
  }
36
  }
37
  }
38
 
39
+ .more-info {
40
+ white-space: nowrap;
41
+ }
42
+
43
  .error {
44
  pre {
45
  background: #eaeaea;
146
  }
147
  }
148
 
149
+ .as3cf-ssl {
150
+ margin-top: 10px;
151
+ p.info {
152
+ margin-top: 10px;
153
+ padding: 0;
154
+ }
155
  }
 
156
 
157
  .as3cf-radio-group {
158
  label {
272
  .as3cf-notice:last-child {
273
  margin-bottom: 0;
274
  }
275
+
276
+ & > p:first-child {
277
+ margin-top: 0;
278
+ }
279
  }
280
 
281
  &:first-of-type {
284
  }
285
  }
286
  }
287
+
288
+ tr.as3cf-bucket-setting .as3cf-defined-in-config {
289
+ float: none;
290
+ }
291
+
292
  h3 {
293
  padding: 0;
294
  margin: 0;
309
  &:hover, &:active {
310
  color: #00a0d2;
311
  }
312
+ &:focus {
313
+ box-shadow: none;
314
+ }
315
  .dashicons-external {
316
  margin-top: -2px;
317
  }
378
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
379
  opacity: 1;
380
  }
381
+
382
+ .as3cf-defined-in-config {
383
+ background: #ccc;
384
+ color: #fff;
385
+ padding: 2px 5px;
386
+ margin: 0 0 5px 5px;
387
+ float: right;
388
+ }
389
+
390
+ .as3cf-defined-setting {
391
+ color: #bbb;
392
+
393
+ label {
394
+ cursor: default;
395
+ }
396
+
397
+ p .more-info a {
398
+ color: #bbb;
399
+ }
400
+
401
+ .as3cf-radio-group p {
402
+ color: #bbb;
403
+ }
404
+
405
+ .as3cf-notice {
406
+ display: none !important;
407
+ }
408
+ }
409
  }
410
 
411
  /**
782
  margin-top: 2px;
783
  font-size: 12px;
784
  color: #a00;
785
+ }
786
+
787
+ .as3cf-notice-toggle-content {
788
+ max-height: 100px;
789
+ overflow-y: scroll;
790
+
791
+ .as3cf-notice-toggle-list {
792
+ margin-top: 0;
793
+ margin-left: 0;
794
+ padding-left: 26px;
795
+ color: #dc3232;
796
+ }
797
  }
classes/amazon-s3-and-cloudfront.php CHANGED
@@ -73,6 +73,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
73
  const DEFAULT_REGION = 'us-east-1';
74
 
75
  const SETTINGS_KEY = 'tantan_wordpress_s3';
 
76
 
77
  /**
78
  * @param string $plugin_file_path
@@ -97,17 +98,20 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
97
  */
98
  function init( $plugin_file_path ) {
99
  self::$plugin_page = $this->plugin_slug;
100
- $this->plugin_title = __( 'Offload S3', 'amazon-s3-and-cloudfront' );
101
  $this->plugin_menu_title = __( 'S3 and CloudFront', 'amazon-s3-and-cloudfront' );
102
 
103
  new AS3CF_Upgrade_Region_Meta( $this );
104
  new AS3CF_Upgrade_File_Sizes( $this );
105
  new AS3CF_Upgrade_Meta_WP_Error( $this );
 
106
 
107
  // Plugin setup
108
  add_action( 'aws_admin_menu', array( $this, 'admin_menu' ) );
109
  add_filter( 'plugin_action_links', array( $this, 'plugin_actions_settings_link' ), 10, 2 );
110
  add_filter( 'pre_get_space_used', array( $this, 'multisite_get_spaced_used' ) );
 
 
111
 
112
  // UI AJAX
113
  add_action( 'wp_ajax_as3cf-get-buckets', array( $this, 'ajax_get_buckets' ) );
@@ -166,6 +170,34 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
166
  return $this->get_plugin_prefix_slug() . '-save-settings';
167
  }
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  /**
170
  * Accessor for a plugin setting with conditions to defaults and upgrades
171
  *
@@ -182,7 +214,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
182
  $value = $_POST[ $key ]; // input var okay
183
  if ( is_array( $value ) ) {
184
  // checkbox is checked
185
- $value = 1;
186
  }
187
  }
188
 
@@ -218,48 +250,37 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
218
  }
219
 
220
  if ( isset( $settings['object-prefix'] ) && '' == trim( $settings['object-prefix'] ) ) {
221
- return 0;
 
 
222
  } else {
223
  return 1;
224
  }
225
  }
226
 
227
- // Region of bucket if not already retrieved
228
- if ( 'region' == $key && ! isset( $settings['region'] ) ) {
229
- $bucket = $this->get_setting( 'bucket' );
230
- $region = $default;
231
- if ( $bucket ) {
232
- $region = $this->get_bucket_region( $bucket );
233
- }
234
-
235
- // Store the region for future use
236
- parent::set_setting( 'region', $region );
237
- $this->save_settings();
238
-
239
  return $region;
240
  }
241
 
242
- // Region of bucket translation
243
- if ( 'region' == $key && isset( $settings['region'] ) ) {
244
-
245
- return $this->translate_region( $settings['region'] );
246
- }
247
-
248
  // Domain setting since 0.8
249
- if ( 'domain' == $key && ! isset( $settings['domain'] ) ) {
250
  if ( $this->get_setting( 'cloudfront' ) ) {
251
  $domain = 'cloudfront';
252
  } elseif ( $this->get_setting( 'virtual-host' ) ) {
253
- $domain = 'virtual-host';
254
- } elseif ( $this->use_ssl() ) {
255
- $domain = 'path';
256
  } else {
257
- $domain = 'subdomain';
258
  }
259
 
260
  return $domain;
261
  }
262
 
 
 
 
 
 
263
  // SSL radio buttons since 0.8
264
  if ( 'ssl' == $key && ! isset( $settings['ssl'] ) ) {
265
  if ( $this->get_setting( 'force-ssl', false ) ) {
@@ -273,8 +294,60 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
273
 
274
  $value = parent::get_setting( $key, $default );
275
 
276
- if ( 'bucket' == $key && defined( 'AS3CF_BUCKET' ) ) {
277
- $bucket = AS3CF_BUCKET;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
 
279
  if ( $bucket !== $value ) {
280
  // Save the defined bucket
@@ -287,7 +360,67 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
287
  return $bucket;
288
  }
289
 
290
- return apply_filters( 'as3cf_setting_' . $key, $value );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
  }
292
 
293
  /**
@@ -324,6 +457,50 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
324
  return $domain;
325
  }
326
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
  /**
328
  * Return the default object prefix
329
  *
@@ -357,13 +534,19 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
357
  * @param null|string $interval Defaults to hook if not supplied
358
  * @param array $args
359
  */
360
- function schedule_event( $hook, $interval = null, $args = array() ) {
361
  if ( is_null( $interval ) ) {
362
  $interval = $hook;
363
  }
 
 
 
 
364
  if ( ! wp_next_scheduled( $hook ) ) {
365
  wp_schedule_event( time(), $interval, $hook, $args );
366
  }
 
 
367
  }
368
 
369
  /**
@@ -371,11 +554,23 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
371
  *
372
  * @param string $hook
373
  */
374
- function clear_scheduled_event( $hook ) {
375
  $timestamp = wp_next_scheduled( $hook );
376
  if ( $timestamp ) {
377
  wp_unschedule_event( $timestamp, $hook );
378
  }
 
 
 
 
 
 
 
 
 
 
 
 
379
  }
380
 
381
  /**
@@ -433,21 +628,28 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
433
  * @param bool $return_on_error
434
  * @param bool $force_new_s3_client if we are deleting in bulk, force new S3 client
435
  * to cope with possible different regions
 
 
436
  */
437
  function delete_s3_objects( $region, $bucket, $objects, $log_error = false, $return_on_error = false, $force_new_s3_client = false ) {
 
 
438
  try {
439
- $this->get_s3client( $region, $force_new_s3_client )->deleteObjects( array(
440
- 'Bucket' => $bucket,
441
- 'Objects' => $objects,
442
- ) );
 
 
443
  } catch ( Exception $e ) {
444
  if ( $log_error ) {
445
- error_log( 'Error removing files from S3: ' . $e->getMessage() );
446
- }
447
- if ( $return_on_error ) {
448
- return;
449
  }
 
 
450
  }
 
 
451
  }
452
 
453
  /**
@@ -617,7 +819,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
617
  $time = date( 'Y/m', $time );
618
  }
619
 
620
- $prefix = $this->get_file_prefix( $time, $post_id );
621
 
622
  // use bucket from settings
623
  $bucket = $this->get_setting( 'bucket' );
@@ -644,17 +846,23 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
644
  $s3client = $this->get_s3client( $region, $force_new_s3_client );
645
 
646
  $args = array(
647
- 'Bucket' => $bucket,
648
- 'Key' => $prefix . $file_name,
649
- 'SourceFile' => $file_path,
650
- 'ACL' => $acl,
 
 
 
651
  );
652
 
653
- // If far future expiration checked (10 years)
654
- if ( $this->get_setting( 'expires' ) ) {
655
- $args['CacheControl'] = 'max-age=315360000';
656
- $args['Expires'] = date( 'D, d M Y H:i:s O', time() + 315360000 );
 
 
657
  }
 
658
  $args = apply_filters( 'as3cf_object_meta', $args, $post_id );
659
 
660
  do_action( 'as3cf_upload_attachment_pre_remove', $post_id, $s3object, $prefix, $args );
@@ -725,7 +933,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
725
  $s3client->putObject( $args );
726
  }
727
  catch ( Exception $e ) {
728
- error_log( 'Error uploading ' . $args['SourceFile'] . ' to S3: ' . $e->getMessage() );
729
  }
730
  }
731
 
@@ -771,6 +979,51 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
771
  return $s3object;
772
  }
773
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
774
  /**
775
  * Helper to return meta data on upload error
776
  *
@@ -784,7 +1037,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
784
  return new WP_Error( 'exception', $error_msg );
785
  }
786
 
787
- error_log( $error_msg );
788
 
789
  return $return;
790
  }
@@ -796,25 +1049,16 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
796
  */
797
  function remove_local_files( $file_paths ) {
798
  foreach ( $file_paths as $path ) {
 
 
 
 
799
  if ( ! @unlink( $path ) ) {
800
- error_log( 'Error removing local file ' . $path );
801
  }
802
  }
803
  }
804
 
805
- /**
806
- * Add HiDPi suffix to a file path
807
- *
808
- * @param string $orig_path
809
- *
810
- * @return string
811
- */
812
- function get_hidpi_file_path( $orig_path ) {
813
- $hidpi_suffix = apply_filters( 'as3cf_hidpi_suffix', '@2x' );
814
-
815
- return $this->apply_file_suffix( $orig_path, $hidpi_suffix );
816
- }
817
-
818
  /**
819
  * Helper to apply a suffix to a file path
820
  *
@@ -832,18 +1076,17 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
832
  /**
833
  * Get the object versioning string prefix
834
  *
835
- * @param int $post_id
836
- *
837
  * @return string
838
  */
839
- function get_object_version_string( $post_id ) {
840
  if ( $this->get_setting( 'use-yearmonth-folders' ) ) {
841
  $date_format = 'dHis';
842
  } else {
843
  $date_format = 'YmdHis';
844
  }
845
 
846
- $time = $this->get_attachment_folder_time( $post_id );
 
847
 
848
  $object_version = date( $date_format, $time ) . '/';
849
  $object_version = apply_filters( 'as3cf_get_object_version_string', $object_version );
@@ -1090,7 +1333,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1090
  * @return mixed
1091
  */
1092
  function get_attachment_s3_info( $post_id ) {
1093
- return get_post_meta( $post_id, 'amazonS3_info', true );
1094
  }
1095
 
1096
  /**
@@ -1199,16 +1442,15 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1199
  * Get the file prefix
1200
  *
1201
  * @param null|string $time
1202
- * @param null|int $post_id
1203
  *
1204
  * @return string
1205
  */
1206
- function get_file_prefix( $time = null, $post_id = null ) {
1207
  $prefix = ltrim( trailingslashit( $this->get_object_prefix() ), '/' );
1208
  $prefix .= ltrim( trailingslashit( $this->get_dynamic_prefix( $time ) ), '/' );
1209
 
1210
  if ( $this->get_setting( 'object-versioning' ) ) {
1211
- $prefix .= $this->get_object_version_string( $post_id );
1212
  }
1213
 
1214
  return $prefix;
@@ -1362,7 +1604,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1362
  }
1363
  }
1364
 
1365
- $file = $this->encode_filename_in_path( $s3object['key'] );
1366
  $url = $scheme . '://' . $domain_bucket . '/' . $file;
1367
 
1368
  return apply_filters( 'as3cf_get_attachment_url', $url, $s3object, $post_id, $expires, $headers );
@@ -1393,7 +1635,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1393
  }
1394
 
1395
  $img_src = $matches[1];
1396
- $encoded_src = $this->encode_filename_in_path( $img_src );
1397
 
1398
  return str_replace( $img_src, $encoded_src, $html );
1399
  }
@@ -1414,7 +1656,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1414
  }
1415
 
1416
  if ( isset( $image[0] ) ) {
1417
- $image[0] = $this->encode_filename_in_path( $image[0] );
1418
  }
1419
 
1420
  return $image;
@@ -1435,12 +1677,12 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1435
  }
1436
 
1437
  if ( isset( $response['url'] ) ) {
1438
- $response['url'] = $this->encode_filename_in_path( $response['url'] );
1439
  }
1440
 
1441
  if ( isset( $response['sizes'] ) && is_array( $response['sizes'] ) ) {
1442
  foreach ( $response['sizes'] as $key => $value ) {
1443
- $response['sizes'][ $key ]['url'] = $this->encode_filename_in_path( $value['url'] );
1444
  }
1445
  }
1446
 
@@ -1462,7 +1704,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1462
  }
1463
 
1464
  if ( isset( $data['url'] ) ) {
1465
- $data['url'] = $this->encode_filename_in_path( $data['url'] );
1466
  }
1467
 
1468
  return $data;
@@ -1494,11 +1736,12 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1494
  * Encode file names according to RFC 3986 when generating urls
1495
  * As per Amazon https://forums.aws.amazon.com/thread.jspa?threadID=55746#jive-message-244233
1496
  *
1497
- * @param string $file
 
1498
  *
1499
  * @return string Encoded filename with path prefix untouched
1500
  */
1501
- function encode_filename_in_path( $file ) {
1502
  $url = parse_url( $file );
1503
 
1504
  if ( ! isset( $url['path'] ) ) {
@@ -1506,7 +1749,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1506
  return $file;
1507
  }
1508
 
1509
- if ( in_array( $this->normalize_file_path( $url['path'] ), $this->encode_files ) ) {
1510
  // Already encoded, return original
1511
  return $file;
1512
  }
@@ -1522,7 +1765,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1522
  return $file;
1523
  }
1524
 
1525
- $normalized_file_path = $this->normalize_file_path( $encoded_file_path );
1526
 
1527
  if ( ! in_array( $normalized_file_path, $this->encode_files ) ) {
1528
  $this->encode_files[] = $normalized_file_path;
@@ -1534,15 +1777,30 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1534
  /**
1535
  * Normalize file path
1536
  *
1537
- * @param string $path
 
1538
  *
1539
  * @return string mixed
1540
  */
1541
- function normalize_file_path( $path ) {
1542
  $url = parse_url( $path );
1543
 
1544
  if ( isset( $url['scheme'] ) ) {
1545
  $path = str_replace( $url['scheme'] . '://', '', $path );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1546
  }
1547
 
1548
  return '/' . ltrim( $path, '/' );
@@ -1902,7 +2160,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1902
  } catch ( Exception $e ) {
1903
  $error_msg_title = '<strong>' . __( 'Error Getting Bucket Region', 'amazon-s3-and-cloudfront' ) . '</strong> &mdash;';
1904
  $error_msg = sprintf( __( 'There was an error attempting to get the region of the bucket %s: %s', 'amazon-s3-and-cloudfront' ), $bucket, $e->getMessage() );
1905
- error_log( $error_msg );
1906
 
1907
  return new WP_Error( 'exception', $error_msg_title . $error_msg );
1908
  }
@@ -2054,7 +2312,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2054
  // if we encounter an error that isn't access denied, throw that error
2055
  if ( ! $e instanceof Aws\Common\Exception\ServiceResponseException || 'AccessDenied' !== $e->getExceptionCode() ) {
2056
  $error_msg = sprintf( __( 'There was an error attempting to check the permissions of the bucket %s: %s', 'amazon-s3-and-cloudfront' ), $bucket, $e->getMessage() );
2057
- error_log( $error_msg );
2058
 
2059
  return new WP_Error( 'exception', $error_msg );
2060
  }
@@ -2086,8 +2344,8 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2086
  * Register modal scripts and styles so they can be enqueued later
2087
  */
2088
  function register_modal_assets() {
2089
- $version = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? time() : $this->plugin_version;
2090
- $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
2091
 
2092
  $src = plugins_url( 'assets/css/modal.css', $this->plugin_file_path );
2093
  wp_register_style( 'as3cf-modal', $src, array(), $version );
@@ -2097,8 +2355,8 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2097
  }
2098
 
2099
  function plugin_load() {
2100
- $version = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? time() : $this->plugin_version;
2101
- $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
2102
 
2103
  $src = plugins_url( 'assets/css/styles.css', $this->plugin_file_path );
2104
  wp_enqueue_style( 'as3cf-styles', $src, array( 'as3cf-modal' ), $version );
@@ -2149,7 +2407,6 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2149
  'region',
2150
  'domain',
2151
  'virtual-host',
2152
- 'expires',
2153
  'permissions',
2154
  'cloudfront',
2155
  'object-prefix',
@@ -2157,7 +2414,6 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2157
  'serve-from-s3',
2158
  'remove-local-file',
2159
  'ssl',
2160
- 'hidpi-images',
2161
  'object-versioning',
2162
  'use-yearmonth-folders',
2163
  'enable-object-prefix',
@@ -2217,7 +2473,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2217
  'page' => self::$plugin_page,
2218
  );
2219
 
2220
- $args = array_merge( $args, $default_args );
2221
 
2222
  switch ( $url_method ) {
2223
  case 'self':
@@ -2288,7 +2544,8 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2288
  }
2289
 
2290
  /**
2291
- * Get the prefix path for the files
 
2292
  *
2293
  * @param string $time
2294
  *
@@ -2296,9 +2553,50 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2296
  */
2297
  function get_dynamic_prefix( $time = null ) {
2298
  $prefix = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2299
  if ( $this->get_setting( 'use-yearmonth-folders' ) ) {
2300
- $uploads = wp_upload_dir( $time );
2301
- $prefix = str_replace( $this->get_base_upload_path(), '', $uploads['path'] );
2302
  }
2303
 
2304
  // support legacy MS installs (<3.5 since upgraded) for subsites
@@ -2306,33 +2604,38 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2306
  $details = get_blog_details( get_current_blog_id() );
2307
  $legacy_ms_prefix = 'sites/' . $details->blog_id . '/';
2308
  $legacy_ms_prefix = apply_filters( 'as3cf_legacy_ms_subsite_prefix', $legacy_ms_prefix, $details );
2309
- $prefix = '/' . trailingslashit( ltrim( $legacy_ms_prefix, '/' ) ) . ltrim( $prefix, '/' );
2310
  }
2311
 
2312
  return $prefix;
2313
  }
2314
 
2315
  /**
2316
- * Get the base upload path
2317
- * without the multisite subdirectory
 
 
2318
  *
2319
  * @return string
2320
  */
2321
- function get_base_upload_path() {
2322
- if ( defined( 'UPLOADS' ) && ! ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) ) {
2323
- return ABSPATH . UPLOADS;
2324
  }
2325
 
2326
- $upload_path = trim( get_option( 'upload_path' ) );
 
 
2327
 
2328
- if ( empty( $upload_path ) || 'wp-content/uploads' == $upload_path ) {
2329
- return WP_CONTENT_DIR . '/uploads';
2330
- } elseif ( 0 !== strpos( $upload_path, ABSPATH ) ) {
2331
- // $dir is absolute, $upload_path is (maybe) relative to ABSPATH
2332
- return path_join( ABSPATH, $upload_path );
2333
- } else {
2334
- return $upload_path;
2335
  }
 
 
2336
  }
2337
 
2338
  /**
@@ -2392,9 +2695,15 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2392
  * @param int $post_id
2393
  * @param array $s3object
2394
  * @param string $acl
 
 
2395
  */
2396
  function set_attachment_acl_on_s3( $post_id, $s3object, $acl ) {
2397
- // set ACL as private
 
 
 
 
2398
  $args = array(
2399
  'ACL' => $acl,
2400
  'Bucket' => $s3object['bucket'],
@@ -2408,49 +2717,84 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2408
  $s3client->PutObjectAcl( $args );
2409
  $s3object['acl'] = $acl;
2410
 
2411
- // Add attachment to ACL update notice
2412
- $message = $this->make_acl_admin_notice_text( $s3object );
2413
- $this->notices->add_notice( $message );
2414
-
2415
  // update S3 meta data
2416
  if ( $acl == self::DEFAULT_ACL ) {
2417
  unset( $s3object['acl'] );
2418
  }
2419
  update_post_meta( $post_id, 'amazonS3_info', $s3object );
2420
  } catch ( Exception $e ) {
2421
- error_log( 'Error setting ACL to ' . $acl . ' for ' . $s3object['key'] . ': ' . $e->getMessage() );
 
 
 
2422
  }
 
 
2423
  }
2424
 
2425
  /**
2426
- * Make admin notice text for when object ACL has changed
2427
  *
2428
  * @param array $s3object
2429
- *
2430
- * @return string
2431
  */
2432
- function make_acl_admin_notice_text( $s3object ) {
2433
  $filename = basename( $s3object['key'] );
2434
- $acl = $this->get_acl_display_name( $s3object['acl'] );
 
 
2435
 
2436
- return sprintf( __( 'The file %s has been given %s permissions on Amazon S3.', 'amazon-s3-and-cloudfront' ), "<strong>{$filename}</strong>", "<strong>{$acl}</strong>" );
2437
  }
2438
 
2439
  /**
2440
  * Check if PHP GD and Imagick is installed
2441
  */
2442
  function check_for_gd_imagick() {
 
 
 
 
 
2443
  $gd_enabled = $this->gd_enabled();
2444
  $imagick_enabled = $this->imagick_enabled();
2445
 
2446
  if( ! $gd_enabled && ! $imagick_enabled ) {
2447
  $this->notices->add_notice(
2448
- __( '<strong>Image Manipulation Library Missing</strong> &mdash; Looks like you don\'t have an image manipulation library installed on this server and configured with PHP. You may run into trouble if you try to edit images. Please setup GD or ImageMagick.', 'amazon-s3-and-cloudfront' ),
2449
  array( 'flash' => false, 'only_show_to_user' => false, 'only_show_in_settings' => true )
2450
  );
2451
  }
2452
  }
2453
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2454
  /**
2455
  * Diagnostic information for the support tab
2456
  *
@@ -2480,6 +2824,9 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2480
  echo bloginfo( 'version' );
2481
  if ( is_multisite() ) {
2482
  echo ' Multisite';
 
 
 
2483
  }
2484
  echo "\r\n";
2485
 
@@ -2494,7 +2841,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2494
  echo "\r\n";
2495
 
2496
  echo 'MySQL: ';
2497
- echo esc_html( empty( $wpdb->use_mysqli ) ? mysql_get_server_info() : mysqli_get_server_info( $wpdb->dbh ) );
2498
  echo "\r\n";
2499
 
2500
  echo 'ext/mysqli: ';
@@ -2529,10 +2876,26 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2529
  echo esc_html( get_locale() );
2530
  echo "\r\n";
2531
 
2532
- echo 'Debug Mode: ';
 
 
 
 
2533
  echo esc_html( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? 'Yes' : 'No' );
2534
  echo "\r\n";
2535
 
 
 
 
 
 
 
 
 
 
 
 
 
2536
  echo 'WP Max Upload Size: ';
2537
  echo esc_html( size_format( wp_max_upload_size() ) );
2538
  echo "\r\n";
@@ -2617,6 +2980,48 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2617
  echo number_format_i18n( $sizes );
2618
  echo "\r\n\r\n";
2619
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2620
  echo 'Bucket: ';
2621
  echo $this->get_setting( 'bucket' );
2622
  echo "\r\n";
@@ -2659,12 +3064,6 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2659
  echo "\r\n";
2660
  echo 'Object Versioning: ';
2661
  echo $this->on_off( 'object-versioning' );
2662
- echo "\r\n";
2663
- echo 'Far Future Expiration Header: ';
2664
- echo $this->on_off( 'expires' );
2665
- echo "\r\n";
2666
- echo 'Copy HiDPI (@2x) Images: ';
2667
- echo $this->on_off( 'hidpi-images' );
2668
  echo "\r\n\r\n";
2669
 
2670
  do_action( 'as3cf_diagnostic_info' );
@@ -2672,6 +3071,18 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2672
  echo "\r\n";
2673
  }
2674
 
 
 
 
 
 
 
 
 
 
 
 
 
2675
  echo "Active Plugins:\r\n";
2676
  $active_plugins = (array) get_option( 'active_plugins', array() );
2677
  $plugin_details = array();
@@ -2777,6 +3188,8 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2777
  * @return string
2778
  */
2779
  function get_acl_display_name( $acl ) {
 
 
2780
  return ucwords( str_replace( '-', ' ', $acl ) );
2781
  }
2782
 
@@ -2841,23 +3254,27 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2841
  * - If the site is MS
2842
  * - If the blog is not the current blog defined
2843
  *
2844
- * @param $blog_id
2845
  */
2846
- function switch_to_blog( $blog_id ) {
2847
- if ( is_multisite() && ! $this->is_current_blog( $blog_id ) ) {
 
 
 
 
 
 
 
 
2848
  switch_to_blog( $blog_id );
2849
  }
2850
  }
2851
 
2852
  /**
2853
  * Helper to restore to the current Multisite blog
2854
- * - If the site is MS
2855
- * - If the blog is not the current blog defined
2856
- *
2857
- * @param $blog_id
2858
  */
2859
- function restore_current_blog( $blog_id ) {
2860
- if ( is_multisite() && ! $this->is_current_blog( $blog_id ) ) {
2861
  restore_current_blog();
2862
  }
2863
  }
@@ -2942,13 +3359,6 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2942
  }
2943
  }
2944
 
2945
- // HiDPI
2946
- if ( $this->get_setting( 'hidpi-images' ) ) {
2947
- foreach ( $paths as $path ) {
2948
- $paths[] = $this->get_hidpi_file_path( $path );
2949
- }
2950
- }
2951
-
2952
  // Allow other processes to add files to be uploaded
2953
  $paths = apply_filters( 'as3cf_attachment_file_paths', $paths, $attachment_id, $meta );
2954
 
@@ -2975,7 +3385,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2975
  * @return string
2976
  */
2977
  function get_access_denied_notice_message( $single = true ) {
2978
- $quick_start = sprintf( '<a class="js-link" href="%s">%s</a>', 'https://deliciousbrains.com/wp-offload-s3/doc/quick-start-guide/', __( 'Quick Start Guide', 'amazon-s3-and-cloudfront' ) );
2979
 
2980
  $message = sprintf( __( "Looks like we don't have write access to this bucket. It's likely that the user you've provided access keys for hasn't been granted the correct permissions. Please see our %s for instructions on setting up permissions correctly.", 'amazon-s3-and-cloudfront' ), $quick_start );
2981
  if ( ! $single ) {
@@ -3123,4 +3533,155 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
3123
 
3124
  return $attachment_counts;
3125
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3126
  }
73
  const DEFAULT_REGION = 'us-east-1';
74
 
75
  const SETTINGS_KEY = 'tantan_wordpress_s3';
76
+ const SETTINGS_CONSTANT = 'WPOS3_SETTINGS';
77
 
78
  /**
79
  * @param string $plugin_file_path
98
  */
99
  function init( $plugin_file_path ) {
100
  self::$plugin_page = $this->plugin_slug;
101
+ $this->plugin_title = __( 'Offload S3 Lite', 'amazon-s3-and-cloudfront' );
102
  $this->plugin_menu_title = __( 'S3 and CloudFront', 'amazon-s3-and-cloudfront' );
103
 
104
  new AS3CF_Upgrade_Region_Meta( $this );
105
  new AS3CF_Upgrade_File_Sizes( $this );
106
  new AS3CF_Upgrade_Meta_WP_Error( $this );
107
+ $this->maybe_display_deprecated_retina_notice();
108
 
109
  // Plugin setup
110
  add_action( 'aws_admin_menu', array( $this, 'admin_menu' ) );
111
  add_filter( 'plugin_action_links', array( $this, 'plugin_actions_settings_link' ), 10, 2 );
112
  add_filter( 'pre_get_space_used', array( $this, 'multisite_get_spaced_used' ) );
113
+ // display a notice when either lite or pro is automatically deactivated
114
+ add_action( 'pre_current_active_plugins', array( $this, 'plugin_deactivated_notice' ) );
115
 
116
  // UI AJAX
117
  add_action( 'wp_ajax_as3cf-get-buckets', array( $this, 'ajax_get_buckets' ) );
170
  return $this->get_plugin_prefix_slug() . '-save-settings';
171
  }
172
 
173
+ /**
174
+ * Gets arguements used to render a setting view.
175
+ *
176
+ * @param string $key
177
+ *
178
+ * @return array
179
+ */
180
+ function get_setting_args( $key ) {
181
+ $is_defined = $this->get_defined_setting( $key, false );
182
+
183
+ $args = array(
184
+ 'key' => $key,
185
+ 'disabled' => false,
186
+ 'disabled_attr' => '',
187
+ 'tr_class' => '',
188
+ 'setting_msg' => '',
189
+ );
190
+
191
+ if ( false !== $is_defined ) {
192
+ $args['disabled'] = true;
193
+ $args['disabled_attr'] = 'disabled="disabled"';
194
+ $args['tr_class'] = 'as3cf-defined-setting';
195
+ $args['setting_msg'] = '<span class="as3cf-defined-in-config">' . __( 'defined in wp-config.php', 'as3cf' ) . '</span>';
196
+ }
197
+
198
+ return $args;
199
+ }
200
+
201
  /**
202
  * Accessor for a plugin setting with conditions to defaults and upgrades
203
  *
214
  $value = $_POST[ $key ]; // input var okay
215
  if ( is_array( $value ) ) {
216
  // checkbox is checked
217
+ $value = $value[1];
218
  }
219
  }
220
 
250
  }
251
 
252
  if ( isset( $settings['object-prefix'] ) && '' == trim( $settings['object-prefix'] ) ) {
253
+ if ( false === $this->get_defined_setting( 'object-prefix', false ) ) {
254
+ return 0;
255
+ }
256
  } else {
257
  return 1;
258
  }
259
  }
260
 
261
+ // Region
262
+ if ( false !== ( $region = $this->get_setting_region( $settings, $key, $default ) ) ) {
 
 
 
 
 
 
 
 
 
 
263
  return $region;
264
  }
265
 
 
 
 
 
 
 
266
  // Domain setting since 0.8
267
+ if ( 'domain' === $key && ! isset( $settings['domain'] ) ) {
268
  if ( $this->get_setting( 'cloudfront' ) ) {
269
  $domain = 'cloudfront';
270
  } elseif ( $this->get_setting( 'virtual-host' ) ) {
271
+ $domain = $this->upgrade_virtual_host();
 
 
272
  } else {
273
+ $domain = 'path';
274
  }
275
 
276
  return $domain;
277
  }
278
 
279
+ // 1.1 Update 'Bucket as Domain' to new CloudFront/Domain UI
280
+ if ( 'domain' === $key && 'virtual-host' === $settings[ $key ] ) {
281
+ return $this->upgrade_virtual_host();
282
+ }
283
+
284
  // SSL radio buttons since 0.8
285
  if ( 'ssl' == $key && ! isset( $settings['ssl'] ) ) {
286
  if ( $this->get_setting( 'force-ssl', false ) ) {
294
 
295
  $value = parent::get_setting( $key, $default );
296
 
297
+ // Bucket
298
+ if ( false !== ( $bucket = $this->get_setting_bucket( $key, $value ) ) ) {
299
+ return $bucket;
300
+ }
301
+
302
+ return apply_filters( 'as3cf_setting_' . $key, $value );
303
+ }
304
+
305
+ /**
306
+ * Get the region setting
307
+ *
308
+ * @param array $settings
309
+ * @param string $key
310
+ * @param mixed $default
311
+ *
312
+ * @return bool|string|WP_Error
313
+ */
314
+ public function get_setting_region( $settings, $key, $default ) {
315
+ // Region of bucket if not already retrieved
316
+ if ( 'region' === $key && ! isset( $settings['region'] ) ) {
317
+ $bucket = $this->get_setting( 'bucket' );
318
+ $region = $default;
319
+ if ( $bucket ) {
320
+ $region = $this->get_bucket_region( $bucket );
321
+ }
322
+
323
+ // Store the region for future use
324
+ parent::set_setting( 'region', $region );
325
+ $this->save_settings();
326
+
327
+ return $region;
328
+ }
329
+
330
+ // Region of bucket translation
331
+ if ( 'region' === $key && isset( $settings['region'] ) ) {
332
+
333
+ return $this->translate_region( $settings['region'] );
334
+ }
335
+
336
+ return false;
337
+ }
338
+
339
+ /**
340
+ * Get the bucket and if a constant save to database and clear region
341
+ *
342
+ * @param string $key
343
+ * @param string $value
344
+ * @param string $constant
345
+ *
346
+ * @return string|false
347
+ */
348
+ public function get_setting_bucket( $key, $value, $constant = 'AS3CF_BUCKET' ) {
349
+ if ( 'bucket' === $key && defined( $constant ) ) {
350
+ $bucket = constant( $constant );
351
 
352
  if ( $bucket !== $value ) {
353
  // Save the defined bucket
360
  return $bucket;
361
  }
362
 
363
+ return false;
364
+ }
365
+
366
+ /**
367
+ * Filter in defined settings with sensible defaults.
368
+ *
369
+ * @param array $settings
370
+ *
371
+ * @return array $settings
372
+ */
373
+ function filter_settings( $settings ) {
374
+ $defined_settings = $this->get_defined_settings();
375
+
376
+ // Bail early if there are no defined settings
377
+ if ( empty( $defined_settings ) ) {
378
+ return $settings;
379
+ }
380
+
381
+ foreach ( $defined_settings as $key => $value ) {
382
+ $allowed_values = array();
383
+
384
+ if ( 'domain' === $key ) {
385
+ $allowed_values = array(
386
+ 'subdomain',
387
+ 'path',
388
+ 'virtual-host',
389
+ 'cloudfront',
390
+ );
391
+ }
392
+
393
+ if ( 'ssl' === $key ) {
394
+ $allowed_values = array(
395
+ 'request',
396
+ 'https',
397
+ 'http',
398
+ );
399
+ }
400
+
401
+ $checkboxes = array(
402
+ 'copy-to-s3',
403
+ 'serve-from-s3',
404
+ 'enable-object-prefix',
405
+ 'remove-local-file',
406
+ 'object-versioning',
407
+ );
408
+
409
+ if ( in_array( $key, $checkboxes ) ) {
410
+ $allowed_values = array( '0', '1' );
411
+ }
412
+
413
+ // Unexpected value, remove from defined_settings array.
414
+ if ( ! empty( $allowed_values ) && ! in_array( $value, $allowed_values ) ) {
415
+ $this->remove_defined_setting( $key );
416
+ continue;
417
+ }
418
+
419
+ // Value defined successfully
420
+ $settings[ $key ] = $value;
421
+ }
422
+
423
+ return $settings;
424
  }
425
 
426
  /**
457
  return $domain;
458
  }
459
 
460
+ /**
461
+ * Disables the save button if all settings have been defined.
462
+ *
463
+ * @param string $defined_settings
464
+ *
465
+ * @return string
466
+ */
467
+ function maybe_disable_save_button( $defined_settings = array() ) {
468
+ $attr = 'disabled="disabled"';
469
+ $defined_settings = ! empty( $defined_settings ) ? $defined_settings : $this->get_defined_settings();
470
+ $whitelisted_settings = $this->get_settings_whitelist();
471
+ $settings_to_skip = array(
472
+ 'bucket',
473
+ 'region',
474
+ 'permissions',
475
+ 'virtual-host',
476
+ );
477
+
478
+ foreach ( $whitelisted_settings as $setting ) {
479
+ if ( in_array( $setting, $settings_to_skip ) ) {
480
+ continue;
481
+ }
482
+
483
+ if ( 'object-prefix' === $setting ) {
484
+ if ( isset( $defined_settings['enable-object-prefix'] ) && '0' === $defined_settings['enable-object-prefix'] ) {
485
+ continue;
486
+ }
487
+ }
488
+
489
+ if ( 'cloudfront' === $setting ) {
490
+ if ( isset( $defined_settings['domain'] ) && 'cloudfront' !== $defined_settings['domain'] ) {
491
+ continue;
492
+ }
493
+ }
494
+
495
+ if ( ! isset( $defined_settings[ $setting ] ) ) {
496
+ // If we're here, there's a setting that hasn't been defined.
497
+ return '';
498
+ }
499
+ }
500
+
501
+ return $attr;
502
+ }
503
+
504
  /**
505
  * Return the default object prefix
506
  *
534
  * @param null|string $interval Defaults to hook if not supplied
535
  * @param array $args
536
  */
537
+ public function schedule_event( $hook, $interval = null, $args = array() ) {
538
  if ( is_null( $interval ) ) {
539
  $interval = $hook;
540
  }
541
+
542
+ // Always schedule events on primary blog
543
+ $this->switch_to_blog();
544
+
545
  if ( ! wp_next_scheduled( $hook ) ) {
546
  wp_schedule_event( time(), $interval, $hook, $args );
547
  }
548
+
549
+ $this->restore_current_blog();
550
  }
551
 
552
  /**
554
  *
555
  * @param string $hook
556
  */
557
+ public function clear_scheduled_event( $hook ) {
558
  $timestamp = wp_next_scheduled( $hook );
559
  if ( $timestamp ) {
560
  wp_unschedule_event( $timestamp, $hook );
561
  }
562
+
563
+ if ( is_multisite() ) {
564
+ // Always clear schedule events on primary blog
565
+ $this->switch_to_blog();
566
+
567
+ $timestamp = wp_next_scheduled( $hook );
568
+ if ( $timestamp ) {
569
+ wp_unschedule_event( $timestamp, $hook );
570
+ }
571
+
572
+ $this->restore_current_blog();
573
+ }
574
  }
575
 
576
  /**
628
  * @param bool $return_on_error
629
  * @param bool $force_new_s3_client if we are deleting in bulk, force new S3 client
630
  * to cope with possible different regions
631
+ *
632
+ * @return bool
633
  */
634
  function delete_s3_objects( $region, $bucket, $objects, $log_error = false, $return_on_error = false, $force_new_s3_client = false ) {
635
+ $chunks = array_chunk( $objects, 1000 );
636
+
637
  try {
638
+ foreach ( $chunks as $chunk ) {
639
+ $this->get_s3client( $region, $force_new_s3_client )->deleteObjects( array(
640
+ 'Bucket' => $bucket,
641
+ 'Objects' => $chunk,
642
+ ) );
643
+ }
644
  } catch ( Exception $e ) {
645
  if ( $log_error ) {
646
+ AS3CF_Error::log( 'Error removing files from S3: ' . $e->getMessage() );
 
 
 
647
  }
648
+
649
+ return false;
650
  }
651
+
652
+ return true;
653
  }
654
 
655
  /**
819
  $time = date( 'Y/m', $time );
820
  }
821
 
822
+ $prefix = $this->get_file_prefix( $time );
823
 
824
  // use bucket from settings
825
  $bucket = $this->get_setting( 'bucket' );
846
  $s3client = $this->get_s3client( $region, $force_new_s3_client );
847
 
848
  $args = array(
849
+ 'Bucket' => $bucket,
850
+ 'Key' => $prefix . $file_name,
851
+ 'SourceFile' => $file_path,
852
+ 'ACL' => $acl,
853
+ 'ContentType' => $type,
854
+ 'CacheControl' => 'max-age=31536000',
855
+ 'Expires' => date( 'D, d M Y H:i:s O', time() + 31536000 ),
856
  );
857
 
858
+ // Handle gzip on supported items
859
+ if ( $this->should_gzip_file( $file_path, $type ) && false !== ( $gzip_body = gzencode( file_get_contents( $file_path ) ) ) ) {
860
+ unset( $args['SourceFile'] );
861
+
862
+ $args['Body'] = $gzip_body;
863
+ $args['ContentEncoding'] = 'gzip';
864
  }
865
+
866
  $args = apply_filters( 'as3cf_object_meta', $args, $post_id );
867
 
868
  do_action( 'as3cf_upload_attachment_pre_remove', $post_id, $s3object, $prefix, $args );
933
  $s3client->putObject( $args );
934
  }
935
  catch ( Exception $e ) {
936
+ AS3CF_Error::log( 'Error uploading ' . $args['SourceFile'] . ' to S3: ' . $e->getMessage() );
937
  }
938
  }
939
 
979
  return $s3object;
980
  }
981
 
982
+ /**
983
+ * Should gzip file
984
+ *
985
+ * @param string $file_path
986
+ * @param string $type
987
+ *
988
+ * @return bool
989
+ */
990
+ protected function should_gzip_file( $file_path, $type ) {
991
+ $mimes = $this->get_mime_types_to_gzip( true );
992
+
993
+ if ( in_array( $type, $mimes ) && is_readable( $file_path ) ) {
994
+ return true;
995
+ }
996
+
997
+ return false;
998
+ }
999
+
1000
+ /**
1001
+ * Get mime types to gzip
1002
+ *
1003
+ * @param bool $media_library
1004
+ *
1005
+ * @return array
1006
+ */
1007
+ protected function get_mime_types_to_gzip( $media_library = false ) {
1008
+ $mimes = apply_filters( 'as3cf_gzip_mime_types', array(
1009
+ 'css' => 'text/css',
1010
+ 'eot' => 'application/vnd.ms-fontobject',
1011
+ 'html' => 'text/html',
1012
+ 'ico' => 'image/x-icon',
1013
+ 'js' => 'application/javascript',
1014
+ 'json' => 'application/json',
1015
+ 'otf' => 'application/x-font-opentype',
1016
+ 'rss' => 'application/rss+xml',
1017
+ 'svg' => 'image/svg+xml',
1018
+ 'ttf' => 'application/x-font-ttf',
1019
+ 'woff' => 'application/font-woff',
1020
+ 'woff2' => 'application/font-woff2',
1021
+ 'xml' => 'application/xml',
1022
+ ), $media_library );
1023
+
1024
+ return $mimes;
1025
+ }
1026
+
1027
  /**
1028
  * Helper to return meta data on upload error
1029
  *
1037
  return new WP_Error( 'exception', $error_msg );
1038
  }
1039
 
1040
+ AS3CF_Error::log( $error_msg );
1041
 
1042
  return $return;
1043
  }
1049
  */
1050
  function remove_local_files( $file_paths ) {
1051
  foreach ( $file_paths as $path ) {
1052
+ if ( false !== ( $pre = apply_filters( 'as3cf_preserve_file_from_local_removal', false, $path ) ) ) {
1053
+ continue;
1054
+ }
1055
+
1056
  if ( ! @unlink( $path ) ) {
1057
+ AS3CF_Error::log( 'Error removing local file ' . $path );
1058
  }
1059
  }
1060
  }
1061
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1062
  /**
1063
  * Helper to apply a suffix to a file path
1064
  *
1076
  /**
1077
  * Get the object versioning string prefix
1078
  *
 
 
1079
  * @return string
1080
  */
1081
+ function get_object_version_string() {
1082
  if ( $this->get_setting( 'use-yearmonth-folders' ) ) {
1083
  $date_format = 'dHis';
1084
  } else {
1085
  $date_format = 'YmdHis';
1086
  }
1087
 
1088
+ // Use current time so that object version is unique
1089
+ $time = current_time( 'timestamp' );
1090
 
1091
  $object_version = date( $date_format, $time ) . '/';
1092
  $object_version = apply_filters( 'as3cf_get_object_version_string', $object_version );
1333
  * @return mixed
1334
  */
1335
  function get_attachment_s3_info( $post_id ) {
1336
+ return apply_filters( 'as3cf_get_attachment_s3_info', get_post_meta( $post_id, 'amazonS3_info', true ), $post_id );
1337
  }
1338
 
1339
  /**
1442
  * Get the file prefix
1443
  *
1444
  * @param null|string $time
 
1445
  *
1446
  * @return string
1447
  */
1448
+ function get_file_prefix( $time = null ) {
1449
  $prefix = ltrim( trailingslashit( $this->get_object_prefix() ), '/' );
1450
  $prefix .= ltrim( trailingslashit( $this->get_dynamic_prefix( $time ) ), '/' );
1451
 
1452
  if ( $this->get_setting( 'object-versioning' ) ) {
1453
+ $prefix .= $this->get_object_version_string();
1454
  }
1455
 
1456
  return $prefix;
1604
  }
1605
  }
1606
 
1607
+ $file = $this->encode_filename_in_path( $s3object['key'], $post_id );
1608
  $url = $scheme . '://' . $domain_bucket . '/' . $file;
1609
 
1610
  return apply_filters( 'as3cf_get_attachment_url', $url, $s3object, $post_id, $expires, $headers );
1635
  }
1636
 
1637
  $img_src = $matches[1];
1638
+ $encoded_src = $this->encode_filename_in_path( $img_src, $id );
1639
 
1640
  return str_replace( $img_src, $encoded_src, $html );
1641
  }
1656
  }
1657
 
1658
  if ( isset( $image[0] ) ) {
1659
+ $image[0] = $this->encode_filename_in_path( $image[0], $attachment_id );
1660
  }
1661
 
1662
  return $image;
1677
  }
1678
 
1679
  if ( isset( $response['url'] ) ) {
1680
+ $response['url'] = $this->encode_filename_in_path( $response['url'], $attachment->ID );
1681
  }
1682
 
1683
  if ( isset( $response['sizes'] ) && is_array( $response['sizes'] ) ) {
1684
  foreach ( $response['sizes'] as $key => $value ) {
1685
+ $response['sizes'][ $key ]['url'] = $this->encode_filename_in_path( $value['url'], $attachment->ID );
1686
  }
1687
  }
1688
 
1704
  }
1705
 
1706
  if ( isset( $data['url'] ) ) {
1707
+ $data['url'] = $this->encode_filename_in_path( $data['url'], $post_id );
1708
  }
1709
 
1710
  return $data;
1736
  * Encode file names according to RFC 3986 when generating urls
1737
  * As per Amazon https://forums.aws.amazon.com/thread.jspa?threadID=55746#jive-message-244233
1738
  *
1739
+ * @param string $file
1740
+ * @param null|int $attachment_id
1741
  *
1742
  * @return string Encoded filename with path prefix untouched
1743
  */
1744
+ function encode_filename_in_path( $file, $attachment_id = null ) {
1745
  $url = parse_url( $file );
1746
 
1747
  if ( ! isset( $url['path'] ) ) {
1749
  return $file;
1750
  }
1751
 
1752
+ if ( in_array( $this->normalize_file_path( $url['path'], $attachment_id ), $this->encode_files ) ) {
1753
  // Already encoded, return original
1754
  return $file;
1755
  }
1765
  return $file;
1766
  }
1767
 
1768
+ $normalized_file_path = $this->normalize_file_path( $encoded_file_path, $attachment_id );
1769
 
1770
  if ( ! in_array( $normalized_file_path, $this->encode_files ) ) {
1771
  $this->encode_files[] = $normalized_file_path;
1777
  /**
1778
  * Normalize file path
1779
  *
1780
+ * @param string $path
1781
+ * @param null|int $attachment_id
1782
  *
1783
  * @return string mixed
1784
  */
1785
+ public function normalize_file_path( $path, $attachment_id = null ) {
1786
  $url = parse_url( $path );
1787
 
1788
  if ( isset( $url['scheme'] ) ) {
1789
  $path = str_replace( $url['scheme'] . '://', '', $path );
1790
+ } else {
1791
+ $path = ltrim( $path, '/' );
1792
+
1793
+ if ( ! is_null( $attachment_id ) ) {
1794
+ // Attempt to remove bucket from path using amazonS3_info key
1795
+ $s3info = $this->get_attachment_s3_info( $attachment_id );
1796
+ $bucket = $s3info['bucket'];
1797
+ } else {
1798
+ // Attempt to remove bucket from path using tantan key
1799
+ $bucket = $this->get_setting( 'bucket' );
1800
+ }
1801
+
1802
+ $preg = '/^' . preg_quote( $bucket ) . '/';
1803
+ $path = preg_replace( $preg, '', $path );
1804
  }
1805
 
1806
  return '/' . ltrim( $path, '/' );
2160
  } catch ( Exception $e ) {
2161
  $error_msg_title = '<strong>' . __( 'Error Getting Bucket Region', 'amazon-s3-and-cloudfront' ) . '</strong> &mdash;';
2162
  $error_msg = sprintf( __( 'There was an error attempting to get the region of the bucket %s: %s', 'amazon-s3-and-cloudfront' ), $bucket, $e->getMessage() );
2163
+ AS3CF_Error::log( $error_msg );
2164
 
2165
  return new WP_Error( 'exception', $error_msg_title . $error_msg );
2166
  }
2312
  // if we encounter an error that isn't access denied, throw that error
2313
  if ( ! $e instanceof Aws\Common\Exception\ServiceResponseException || 'AccessDenied' !== $e->getExceptionCode() ) {
2314
  $error_msg = sprintf( __( 'There was an error attempting to check the permissions of the bucket %s: %s', 'amazon-s3-and-cloudfront' ), $bucket, $e->getMessage() );
2315
+ AS3CF_Error::log( $error_msg );
2316
 
2317
  return new WP_Error( 'exception', $error_msg );
2318
  }
2344
  * Register modal scripts and styles so they can be enqueued later
2345
  */
2346
  function register_modal_assets() {
2347
+ $version = $this->get_asset_version();
2348
+ $suffix = $this->get_asset_suffix();
2349
 
2350
  $src = plugins_url( 'assets/css/modal.css', $this->plugin_file_path );
2351
  wp_register_style( 'as3cf-modal', $src, array(), $version );
2355
  }
2356
 
2357
  function plugin_load() {
2358
+ $version = $this->get_asset_version();
2359
+ $suffix = $this->get_asset_suffix();
2360
 
2361
  $src = plugins_url( 'assets/css/styles.css', $this->plugin_file_path );
2362
  wp_enqueue_style( 'as3cf-styles', $src, array( 'as3cf-modal' ), $version );
2407
  'region',
2408
  'domain',
2409
  'virtual-host',
 
2410
  'permissions',
2411
  'cloudfront',
2412
  'object-prefix',
2414
  'serve-from-s3',
2415
  'remove-local-file',
2416
  'ssl',
 
2417
  'object-versioning',
2418
  'use-yearmonth-folders',
2419
  'enable-object-prefix',
2473
  'page' => self::$plugin_page,
2474
  );
2475
 
2476
+ $args = array_merge( $default_args, $args );
2477
 
2478
  switch ( $url_method ) {
2479
  case 'self':
2544
  }
2545
 
2546
  /**
2547
+ * Get the prefix path for the files. Ignores WP media library
2548
+ * year month subdirectory setting and just uses S3 setting
2549
  *
2550
  * @param string $time
2551
  *
2553
  */
2554
  function get_dynamic_prefix( $time = null ) {
2555
  $prefix = '';
2556
+ $subdir = '';
2557
+
2558
+ // If multisite (and if not the main site in a post-MU network)
2559
+ if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) {
2560
+ if ( ! get_site_option( 'ms_files_rewriting' ) ) {
2561
+ /*
2562
+ * If ms-files rewriting is disabled (networks created post-3.5), it is fairly
2563
+ * straightforward: Append sites/%d if we're not on the main site (for post-MU
2564
+ * networks). (The extra directory prevents a four-digit ID from conflicting with
2565
+ * a year-based directory for the main site. But if a MU-era network has disabled
2566
+ * ms-files rewriting manually, they don't need the extra directory, as they never
2567
+ * had wp-content/uploads for the main site.)
2568
+ */
2569
+
2570
+ if ( defined( 'MULTISITE' ) ) {
2571
+ $prefix = '/sites/' . get_current_blog_id();
2572
+ } else {
2573
+ $prefix = '/' . get_current_blog_id();
2574
+ }
2575
+ } elseif ( defined( 'UPLOADS' ) && ! ms_is_switched() ) {
2576
+ /*
2577
+ * Handle the old-form ms-files.php rewriting if the network still has that enabled.
2578
+ * When ms-files rewriting is enabled, then we only listen to UPLOADS when:
2579
+ * 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
+ echo 'WP_DEBUG_DISPLAY: ';
2892
+ echo esc_html( ( defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG_DISPLAY ) ? 'Yes' : 'No' );
2893
+ echo "\r\n";
2894
+
2895
+ echo 'SCRIPT_DEBUG: ';
2896
+ echo esc_html( ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? 'Yes' : 'No' );
2897
+ echo "\r\n";
2898
+
2899
  echo 'WP Max Upload Size: ';
2900
  echo esc_html( size_format( wp_max_upload_size() ) );
2901
  echo "\r\n";
2980
  echo number_format_i18n( $sizes );
2981
  echo "\r\n\r\n";
2982
 
2983
+ echo 'Names and Dimensions of Image Sizes: ';
2984
+ echo "\r\n";
2985
+ $size_details = $this->get_image_sizes_details();
2986
+ echo $size_details;
2987
+ echo "\r\n";
2988
+
2989
+ echo 'WP_CONTENT_DIR: ';
2990
+ echo esc_html( ( defined( 'WP_CONTENT_DIR' ) ) ? WP_CONTENT_DIR : 'Not defined' );
2991
+ echo "\r\n";
2992
+
2993
+ echo 'WP_CONTENT_URL: ';
2994
+ echo esc_html( ( defined( 'WP_CONTENT_URL' ) ) ? WP_CONTENT_URL : 'Not defined' );
2995
+ echo "\r\n";
2996
+
2997
+ echo 'UPLOADS: ';
2998
+ echo esc_html( ( defined( 'UPLOADS' ) ) ? UPLOADS : 'Not defined' );
2999
+ echo "\r\n";
3000
+
3001
+ echo 'WP_PLUGIN_DIR: ';
3002
+ echo esc_html( ( defined( 'WP_PLUGIN_DIR' ) ) ? WP_PLUGIN_DIR : 'Not defined' );
3003
+ echo "\r\n";
3004
+
3005
+ echo 'WP_PLUGIN_URL: ';
3006
+ echo esc_html( ( defined( 'WP_PLUGIN_URL' ) ) ? WP_PLUGIN_URL : 'Not defined' );
3007
+ echo "\r\n\r\n";
3008
+
3009
+ echo 'AWS_USE_EC2_IAM_ROLE: ';
3010
+ echo esc_html( ( defined( 'AWS_USE_EC2_IAM_ROLE' ) ) ? AWS_USE_EC2_IAM_ROLE : 'Not defined' );
3011
+ echo "\r\n";
3012
+
3013
+ echo 'AS3CF_BUCKET: ';
3014
+ echo esc_html( ( defined( 'AS3CF_BUCKET' ) ) ? AS3CF_BUCKET : 'Not defined' );
3015
+ echo "\r\n";
3016
+
3017
+ echo 'AS3CF_ASSETS_BUCKET: ';
3018
+ echo esc_html( ( defined( 'AS3CF_ASSETS_BUCKET' ) ) ? AS3CF_ASSETS_BUCKET : 'Not defined' );
3019
+ echo "\r\n";
3020
+
3021
+ echo 'AS3CF_REGION: ';
3022
+ echo esc_html( ( defined( 'AS3CF_REGION' ) ) ? AS3CF_REGION : 'Not defined' );
3023
+ echo "\r\n\r\n";
3024
+
3025
  echo 'Bucket: ';
3026
  echo $this->get_setting( 'bucket' );
3027
  echo "\r\n";
3064
  echo "\r\n";
3065
  echo 'Object Versioning: ';
3066
  echo $this->on_off( 'object-versioning' );
 
 
 
 
 
 
3067
  echo "\r\n\r\n";
3068
 
3069
  do_action( 'as3cf_diagnostic_info' );
3071
  echo "\r\n";
3072
  }
3073
 
3074
+ $theme_info = wp_get_theme();
3075
+ echo "Active Theme Name: " . esc_html( $theme_info->Name ) . "\r\n";
3076
+ echo "Active Theme Folder: " . esc_html( basename( $theme_info->get_stylesheet_directory() ) ) . "\r\n";
3077
+ if ( $theme_info->get( 'Template' ) ) {
3078
+ echo "Parent Theme Folder: " . esc_html( $theme_info->get( 'Template' ) ) . "\r\n";
3079
+ }
3080
+ if ( ! file_exists( $theme_info->get_stylesheet_directory() ) ) {
3081
+ echo "WARNING: Active Theme Folder Not Found\r\n";
3082
+ }
3083
+
3084
+ echo "\r\n";
3085
+
3086
  echo "Active Plugins:\r\n";
3087
  $active_plugins = (array) get_option( 'active_plugins', array() );
3088
  $plugin_details = array();
3188
  * @return string
3189
  */
3190
  function get_acl_display_name( $acl ) {
3191
+ $acl = ( 'public-read' === $acl ) ? 'public' : $acl;
3192
+
3193
  return ucwords( str_replace( '-', ' ', $acl ) );
3194
  }
3195
 
3254
  * - If the site is MS
3255
  * - If the blog is not the current blog defined
3256
  *
3257
+ * @param int|bool $blog_id
3258
  */
3259
+ public function switch_to_blog( $blog_id = false ) {
3260
+ if ( ! is_multisite() ) {
3261
+ return;
3262
+ }
3263
+
3264
+ if ( ! $blog_id ) {
3265
+ $blog_id = defined( 'BLOG_ID_CURRENT_SITE' ) ? BLOG_ID_CURRENT_SITE : 1;
3266
+ }
3267
+
3268
+ if ( $blog_id !== get_current_blog_id() ) {
3269
  switch_to_blog( $blog_id );
3270
  }
3271
  }
3272
 
3273
  /**
3274
  * Helper to restore to the current Multisite blog
 
 
 
 
3275
  */
3276
+ public function restore_current_blog() {
3277
+ if ( is_multisite() ) {
3278
  restore_current_blog();
3279
  }
3280
  }
3359
  }
3360
  }
3361
 
 
 
 
 
 
 
 
3362
  // Allow other processes to add files to be uploaded
3363
  $paths = apply_filters( 'as3cf_attachment_file_paths', $paths, $attachment_id, $meta );
3364
 
3385
  * @return string
3386
  */
3387
  function get_access_denied_notice_message( $single = true ) {
3388
+ $quick_start = sprintf( '<a class="js-link" href="%s">%s</a>', 'https://deliciousbrains.com/wp-offload-s3/doc/quick-start-guide/#bucket-restrictions', __( 'Quick Start Guide', 'amazon-s3-and-cloudfront' ) );
3389
 
3390
  $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 );
3391
  if ( ! $single ) {
3533
 
3534
  return $attachment_counts;
3535
  }
3536
+
3537
+ /**
3538
+ * Display a notice after either lite or pro plugin has been auto deactivated
3539
+ */
3540
+ function plugin_deactivated_notice() {
3541
+ if ( false !== ( $deactivated_notice_id = get_transient( 'as3cf_deactivated_notice_id' ) ) ) {
3542
+ if ( '1' === $deactivated_notice_id ) {
3543
+ $title = __( 'WP Offload S3 Activation', 'amazon-s3-and-cloudfront' );
3544
+ $message = __( "WP Offload S3 Lite and WP Offload S3 cannot both be active. We've automatically deactivated WP Offload S3 Lite.", 'amazon-s3-and-cloudfront' );
3545
+ } else {
3546
+ $title = __( 'WP Offload S3 Lite Activation', 'amazon-s3-and-cloudfront' );
3547
+ $message = __( "WP Offload S3 Lite and WP Offload S3 cannot both be active. We've automatically deactivated WP Offload S3.", 'amazon-s3-and-cloudfront' );
3548
+ }
3549
+
3550
+ $message = sprintf( '<strong>%s</strong> &mdash; %s', esc_html( $title ), esc_html( $message ) );
3551
+
3552
+ $this->render_view( 'notice', array( 'message' => $message ) );
3553
+
3554
+ delete_transient( 'as3cf_deactivated_notice_id' );
3555
+ }
3556
+ }
3557
+
3558
+ /**
3559
+ * Throw error
3560
+ *
3561
+ * @param string $code
3562
+ * @param string $message
3563
+ * @param mixed $data
3564
+ *
3565
+ * @return WP_Error
3566
+ */
3567
+ public function _throw_error( $code, $message = '', $data = '' ) {
3568
+ return new WP_Error( $code, $message, $data );
3569
+ }
3570
+
3571
+ /**
3572
+ * More info link
3573
+ *
3574
+ * @param string $url
3575
+ * @param string $hash
3576
+ * @param bool $append_campaign
3577
+ *
3578
+ * @return string
3579
+ */
3580
+ public function more_info_link( $url, $hash = '', $append_campaign = true ) {
3581
+ if ( $append_campaign ) {
3582
+ $campaign = $this->is_pro() ? 'os3-pro-plugin' : 'os3-free-plugin';
3583
+ $url .= '?utm_source=insideplugin&utm_medium=web&utm_content=more-info&utm_campaign=' . $campaign;
3584
+ }
3585
+
3586
+ if ( ! empty( $hash ) ) {
3587
+ $url .= '#' . $hash;
3588
+ }
3589
+
3590
+ return sprintf( '<span class="more-info"><a href="%s">%s</a> &raquo;</span>', esc_url( $url ), __( 'More info', 'amazon-s3-and-cloudfront' ) );
3591
+ }
3592
+
3593
+ /**
3594
+ * Settings more info link
3595
+ *
3596
+ * @param string $hash
3597
+ *
3598
+ * @return string
3599
+ */
3600
+ public function settings_more_info_link( $hash ) {
3601
+ return $this->more_info_link( 'https://deliciousbrains.com/wp-offload-s3/doc/settings/', $hash );
3602
+ }
3603
+
3604
+ /**
3605
+ * Helper function for filtering super globals. Easily testable.
3606
+ *
3607
+ * @param string $variable
3608
+ * @param int $type
3609
+ * @param int $filter
3610
+ *
3611
+ * @return mixed
3612
+ */
3613
+ public function filter_input( $variable, $type = INPUT_GET, $filter = FILTER_DEFAULT ) {
3614
+ return filter_input( $type, $variable, $filter );
3615
+ }
3616
+
3617
+ /**
3618
+ * Helper function for terminating script execution. Easily testable.
3619
+ *
3620
+ * @param int|string $exit_code
3621
+ *
3622
+ * @return void
3623
+ */
3624
+ public function _exit( $exit_code = 0 ) {
3625
+ exit( $exit_code );
3626
+ }
3627
+
3628
+ /**
3629
+ * Show the deprecated Domain option setting?
3630
+ *
3631
+ * @param null|string $domain
3632
+ *
3633
+ * @return bool
3634
+ */
3635
+ public function show_deprecated_domain_setting( $domain = null ) {
3636
+ if ( is_null( $domain ) ) {
3637
+ $domain = $this->get_setting( 'domain' );
3638
+ }
3639
+
3640
+ if ( ! in_array( $domain, array( 'path', 'cloudfront' ) ) ) {
3641
+ return true;
3642
+ }
3643
+
3644
+ return apply_filters( 'as3cf_show_deprecated_domain_setting', false );
3645
+ }
3646
+
3647
+ /**
3648
+ * Upgrade the 'virtual host' / 'bucket as domain' setting to the
3649
+ * new CloudFront / Domain setting
3650
+ *
3651
+ * @return string
3652
+ */
3653
+ public function upgrade_virtual_host() {
3654
+ $domain = 'cloudfront';
3655
+ $this->set_setting( 'cloudfront', $this->get_setting( 'bucket' ) );
3656
+ $this->set_setting( 'domain', $domain );
3657
+
3658
+ $this->save_settings();
3659
+
3660
+ return $domain;
3661
+ }
3662
+
3663
+ /**
3664
+ * Display a notice if using the retina hidpi setting when
3665
+ * we removed support for it in 1.1.
3666
+ */
3667
+ protected function maybe_display_deprecated_retina_notice() {
3668
+ if ( ! $this->get_setting( 'hidpi-images' ) ) {
3669
+ // Not using setting, abort
3670
+ return;
3671
+ }
3672
+
3673
+ $notice_args = array(
3674
+ 'type' => 'notice-info',
3675
+ 'only_show_to_user' => false,
3676
+ 'flash' => false,
3677
+ );
3678
+
3679
+ $doc_url = 'https://deliciousbrains.com/wp-offload-s3/doc/copy-hidpi-2x-images-support/';
3680
+ $doc_link = sprintf( '<a href="%s">%s</a>', $doc_url, __( 'this doc' ) );
3681
+
3682
+ $message = sprintf( '<strong>%s</strong> &mdash; ', __( 'WP Offload S3 Feature Removed', 'amazon-s3-and-cloudfront' ) );
3683
+ $message .= sprintf( __( 'The "Copy HiDPI (@2x) Images" feature has been removed as of version 1.1 of WP Offload S3. It looks like you had this feature turned on. Please see %s for why we removed this feature and how you can continue copying @2x images to S3.', 'amazon-s3-and-cloudfront' ), $doc_link );
3684
+
3685
+ $this->notices->add_notice( $message, $notice_args );
3686
+ }
3687
  }
classes/as3cf-error.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Error
4
+ *
5
+ * @package amazon-s3-and-cloudfront
6
+ * @subpackage Classes/Error
7
+ * @copyright Copyright (c) 2015, Delicious Brains
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 0.9.12
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ /**
18
+ * AS3CF_Error Class
19
+ *
20
+ * This class handles error logging
21
+ *
22
+ * @since 0.9.12
23
+ */
24
+ class AS3CF_Error {
25
+
26
+ /**
27
+ * Wrapper for error logging a message with plugin prefix
28
+ *
29
+ * @param mixed $message
30
+ * @param string $plugin_prefix
31
+ */
32
+ public static function log( $message, $plugin_prefix = '' ) {
33
+ $prefix = 'WPOS3';
34
+ if ( '' !== $plugin_prefix ) {
35
+ $prefix .= '_' . $plugin_prefix;
36
+ }
37
+
38
+ $prefix .= ': ';
39
+
40
+ if ( is_array( $message ) || is_object( $message ) ) {
41
+ error_log( $prefix . print_r( $message, true ) );
42
+ } else {
43
+ error_log( $prefix . $message );
44
+ }
45
+ }
46
+ }
classes/as3cf-notices.php CHANGED
@@ -47,6 +47,7 @@ class AS3CF_Notices {
47
 
48
  add_action( 'admin_notices', array( $this, 'admin_notices' ) );
49
  add_action( 'network_admin_notices', array( $this, 'admin_notices' ) );
 
50
  add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_notice_scripts' ) );
51
  add_action( 'wp_ajax_as3cf-dismiss-notice', array( $this, 'ajax_dismiss_notice' ) );
52
  }
@@ -73,10 +74,14 @@ class AS3CF_Notices {
73
  'inline' => false,
74
  'flash' => true,
75
  'only_show_to_user' => true, // The user who has initiated an action resulting in notice. Otherwise show to all users.
 
76
  'only_show_in_settings' => false,
 
77
  'custom_id' => '',
78
  'auto_p' => true, // Automatically wrap the message in a <p>
79
  'class' => '', // Extra classes for the notice
 
 
80
  );
81
 
82
  $notice = array_intersect_key( array_merge( $defaults, $args ), $defaults );
@@ -90,6 +95,10 @@ class AS3CF_Notices {
90
  $notice['id'] = apply_filters( 'as3cf_notice_id_prefix', 'as3cf-notice-' ) . sha1( $notice['message'] );
91
  }
92
 
 
 
 
 
93
  $this->save_notice( $notice );
94
 
95
  return $notice['id'];
@@ -282,8 +291,15 @@ class AS3CF_Notices {
282
 
283
  /**
284
  * Show the notices
 
 
285
  */
286
- public function admin_notices() {
 
 
 
 
 
287
  $user_id = get_current_user_id();
288
  $dismissed_notices = get_user_meta( $user_id, 'as3cf_dismissed_notices', true );
289
  if ( ! is_array( $dismissed_notices ) ) {
@@ -294,14 +310,14 @@ class AS3CF_Notices {
294
  $user_notices = $this->cleanup_corrupt_user_notices( $user_id, $user_notices );
295
  if ( is_array( $user_notices ) && ! empty( $user_notices ) ) {
296
  foreach ( $user_notices as $notice ) {
297
- $this->maybe_show_notice( $notice, $dismissed_notices );
298
  }
299
  }
300
 
301
  $global_notices = get_site_transient( 'as3cf_notices' );
302
  if ( is_array( $global_notices ) && ! empty( $global_notices ) ) {
303
  foreach ( $global_notices as $notice ) {
304
- $this->maybe_show_notice( $notice, $dismissed_notices );
305
  }
306
  }
307
  }
@@ -335,9 +351,11 @@ class AS3CF_Notices {
335
  /**
336
  * If it should be shown, display an individual notice
337
  *
338
- * @param array $notice
 
 
339
  */
340
- protected function maybe_show_notice( $notice, $dismissed_notices ) {
341
  $screen = get_current_screen();
342
  if ( $notice['only_show_in_settings'] && false === strpos( $screen->id, $this->as3cf->hook_suffix ) ) {
343
  return;
@@ -347,6 +365,18 @@ class AS3CF_Notices {
347
  return;
348
  }
349
 
 
 
 
 
 
 
 
 
 
 
 
 
350
  if ( 'info' === $notice['type'] ) {
351
  $notice['type'] = 'notice-info';
352
  }
@@ -358,6 +388,35 @@ class AS3CF_Notices {
358
  }
359
  }
360
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  /**
362
  * Enqueue notice scripts in the admin
363
  */
47
 
48
  add_action( 'admin_notices', array( $this, 'admin_notices' ) );
49
  add_action( 'network_admin_notices', array( $this, 'admin_notices' ) );
50
+ add_action( 'as3cf_pre_tab_render', array( $this, 'admin_notices' ) );
51
  add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_notice_scripts' ) );
52
  add_action( 'wp_ajax_as3cf-dismiss-notice', array( $this, 'ajax_dismiss_notice' ) );
53
  }
74
  'inline' => false,
75
  'flash' => true,
76
  'only_show_to_user' => true, // The user who has initiated an action resulting in notice. Otherwise show to all users.
77
+ 'user_capabilities' => array( 'as3cf_compat_check', 'check_capabilities' ), // A user with these capabilities can see the notice. Can be a callback with the first array item the name of global class instance.
78
  'only_show_in_settings' => false,
79
+ 'only_show_on_tab' => false, // Only show on a specific WP Offload S3 tab.
80
  'custom_id' => '',
81
  'auto_p' => true, // Automatically wrap the message in a <p>
82
  'class' => '', // Extra classes for the notice
83
+ 'show_callback' => false, // Callback to display extra info on notices. Passing a callback automatically handles show/hide toggle.
84
+ 'callback_args' => array(), // Arguments to pass to the callback.
85
  );
86
 
87
  $notice = array_intersect_key( array_merge( $defaults, $args ), $defaults );
95
  $notice['id'] = apply_filters( 'as3cf_notice_id_prefix', 'as3cf-notice-' ) . sha1( $notice['message'] );
96
  }
97
 
98
+ if ( isset( $notice['only_show_on_tab'] ) && false !== $notice['only_show_on_tab'] ) {
99
+ $notice['inline'] = true;
100
+ }
101
+
102
  $this->save_notice( $notice );
103
 
104
  return $notice['id'];
291
 
292
  /**
293
  * Show the notices
294
+ *
295
+ * @param string $tab
296
  */
297
+ public function admin_notices( $tab = '' ) {
298
+ if ( empty( $tab ) ) {
299
+ // Callbacks with no $tab property return empty string, so convert to bool.
300
+ $tab = false;
301
+ }
302
+
303
  $user_id = get_current_user_id();
304
  $dismissed_notices = get_user_meta( $user_id, 'as3cf_dismissed_notices', true );
305
  if ( ! is_array( $dismissed_notices ) ) {
310
  $user_notices = $this->cleanup_corrupt_user_notices( $user_id, $user_notices );
311
  if ( is_array( $user_notices ) && ! empty( $user_notices ) ) {
312
  foreach ( $user_notices as $notice ) {
313
+ $this->maybe_show_notice( $notice, $dismissed_notices, $tab );
314
  }
315
  }
316
 
317
  $global_notices = get_site_transient( 'as3cf_notices' );
318
  if ( is_array( $global_notices ) && ! empty( $global_notices ) ) {
319
  foreach ( $global_notices as $notice ) {
320
+ $this->maybe_show_notice( $notice, $dismissed_notices, $tab );
321
  }
322
  }
323
  }
351
  /**
352
  * If it should be shown, display an individual notice
353
  *
354
+ * @param array $notice
355
+ * @param array $dismissed_notices
356
+ * @param string|bool $tab
357
  */
358
+ protected function maybe_show_notice( $notice, $dismissed_notices, $tab ) {
359
  $screen = get_current_screen();
360
  if ( $notice['only_show_in_settings'] && false === strpos( $screen->id, $this->as3cf->hook_suffix ) ) {
361
  return;
365
  return;
366
  }
367
 
368
+ if ( ! isset( $notice['only_show_on_tab'] ) && false !== $tab ) {
369
+ return;
370
+ }
371
+
372
+ if ( isset( $notice['only_show_on_tab'] ) && $tab !== $notice['only_show_on_tab'] ) {
373
+ return;
374
+ }
375
+
376
+ if ( ! $this->check_capability_for_notice( $notice ) ) {
377
+ return;
378
+ }
379
+
380
  if ( 'info' === $notice['type'] ) {
381
  $notice['type'] = 'notice-info';
382
  }
388
  }
389
  }
390
 
391
+ /**
392
+ * Ensure the user has the correct capabilities for the notice to be displayed.
393
+ *
394
+ * @param array $notice
395
+ *
396
+ * @return bool|mixed
397
+ */
398
+ protected function check_capability_for_notice( $notice ) {
399
+ if ( ! isset( $notice['user_capabilities'] ) || empty( $notice['user_capabilities'] ) ) {
400
+ // No capability restrictions, show the notice
401
+ return true;
402
+ }
403
+
404
+ $caps = $notice['user_capabilities'];
405
+
406
+ if ( 2 === count( $caps ) && isset( $GLOBALS[ $caps[0] ] ) && is_callable( array( $GLOBALS[ $caps[0] ], $caps[1] ) ) ) {
407
+ // Handle callback passed for capabilities
408
+ return call_user_func( array( $GLOBALS[ $caps[0] ], $caps[1] ) );
409
+ }
410
+
411
+ foreach ( $caps as $cap ) {
412
+ if ( is_string( $cap ) && ! current_user_can( $cap ) ) {
413
+ return false;
414
+ }
415
+ }
416
+
417
+ return true;
418
+ }
419
+
420
  /**
421
  * Enqueue notice scripts in the admin
422
  */
classes/as3cf-plugin-compatibility.php CHANGED
@@ -33,6 +33,11 @@ class AS3CF_Plugin_Compatibility {
33
  */
34
  protected static $stream_wrappers = array();
35
 
 
 
 
 
 
36
  /**
37
  * @param Amazon_S3_And_CloudFront $as3cf
38
  */
@@ -53,14 +58,20 @@ class AS3CF_Plugin_Compatibility {
53
  add_filter( 'attachment_url_to_postid', array( $this, 'customizer_background_image' ), 10, 2 );
54
 
55
  /*
56
- * Responsive Images WP 4.4+
57
  */
 
 
58
  global $wp_version;
59
  if ( 0 === version_compare( $wp_version, '4.4' ) ) {
 
60
  add_filter( 'the_content', array( $this, 'wp_make_content_images_responsive' ), 11 );
61
  }
62
 
63
- add_filter( 'wp_calculate_image_srcset', array( $this, 'wp_calculate_image_srcset' ), 10, 5 );
 
 
 
64
 
65
  if ( $this->as3cf->is_plugin_setup() ) {
66
  $this->compatibility_init_if_setup();
@@ -109,11 +120,11 @@ class AS3CF_Plugin_Compatibility {
109
  global $amazon_web_services;
110
 
111
  $all_addons = $amazon_web_services->get_addons( true );
112
- if ( ! isset( $all_addons['amazon-s3-and-cloudfront']['addons']['amazon-s3-and-cloudfront-pro']['addons'] ) ) {
113
  return array();
114
  }
115
 
116
- $addons = $all_addons['amazon-s3-and-cloudfront']['addons']['amazon-s3-and-cloudfront-pro']['addons'];
117
 
118
  return $addons;
119
  }
@@ -124,8 +135,11 @@ class AS3CF_Plugin_Compatibility {
124
  * @return array
125
  */
126
  public function get_compatibility_addons_to_install() {
127
- $addons = $this->get_pro_addons();
 
 
128
 
 
129
  $addons_to_install = array();
130
 
131
  if ( empty ( $addons ) ) {
@@ -154,6 +168,8 @@ class AS3CF_Plugin_Compatibility {
154
  );
155
  }
156
 
 
 
157
  return $addons_to_install;
158
  }
159
 
@@ -172,16 +188,17 @@ class AS3CF_Plugin_Compatibility {
172
  return;
173
  }
174
 
175
- $addons_to_install = $this->get_compatibility_addons_to_install();
176
-
177
- $notice_id = 'as3cf-compat-addons';
178
-
179
- $this->maybe_prepare_compatibility_addons_notice( $notice_id, $addons_to_install );
180
-
181
- if ( empty( $addons_to_install ) ) {
182
  return;
183
  }
184
 
 
 
 
 
 
 
185
  $title = __( 'WP Offload S3 Compatibility Addons', 'amazon-s3-and-cloudfront' );
186
  $compat_url = 'https://deliciousbrains.com/wp-offload-s3/doc/compatibility-with-other-plugins/';
187
  $compat_link = sprintf( '<a href="%s">%s</a>', $compat_url, __( 'compatibility addons', 'amazon-s3-and-cloudfront' ) );
@@ -219,28 +236,50 @@ class AS3CF_Plugin_Compatibility {
219
  }
220
 
221
  /**
222
- * Remove the notice if exists already and undismiss the notice
223
- * if the addons available have changed.
224
  *
225
- * @param int $notice_id
226
- * @param array $addons_to_install
227
  */
228
- protected function maybe_prepare_compatibility_addons_notice( $notice_id, $addons_to_install ) {
229
- $notice = $this->as3cf->notices->find_notice_by_id( $notice_id );
 
230
 
231
- if ( is_null( $notice ) ) {
232
- return;
 
233
  }
234
 
235
- $previous_addons_to_install = get_site_option( 'as3cf_compat_addons_to_install', array() );
 
 
236
 
237
- if ( ! empty( $previous_addons_to_install ) && $addons_to_install !== $previous_addons_to_install ) {
238
- // Remove dismissed flag for all users, so we reshow the notice with new addons
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  $this->as3cf->notices->undismiss_notice_for_all( $notice_id );
 
240
  }
241
 
242
- // Remove the notice so we refresh it later on
243
- $this->as3cf->notices->remove_notice( $notice );
 
244
  }
245
 
246
  /**
@@ -326,10 +365,10 @@ class AS3CF_Plugin_Compatibility {
326
  $var_type = 'GET';
327
 
328
  if ( isset( $_GET['action'] ) ) {
329
- $action = $_GET['action'];
330
  } else if ( isset( $_POST['action'] ) ) {
331
  $var_type = 'POST';
332
- $action = $_POST['action'];
333
  } else {
334
  return false;
335
  }
@@ -337,7 +376,7 @@ class AS3CF_Plugin_Compatibility {
337
  $context_check = true;
338
  if ( ! is_null( $context_key ) ) {
339
  $global = constant( 'INPUT_' . $var_type );
340
- $context = filter_input( $global, 'context' );
341
  $context_check = ( $context_key === $context );
342
  }
343
 
@@ -621,7 +660,16 @@ class AS3CF_Plugin_Compatibility {
621
  *
622
  * @return string|bool File if downloaded, false on failure
623
  */
624
- protected function copy_s3_file_to_server( $s3_object, $file ) {
 
 
 
 
 
 
 
 
 
625
  try {
626
  $this->as3cf->get_s3client( $s3_object['region'], true )->getObject(
627
  array(
@@ -631,7 +679,7 @@ class AS3CF_Plugin_Compatibility {
631
  )
632
  );
633
  } catch ( Exception $e ) {
634
- error_log( sprintf( __( 'There was an error attempting to download the file %s from S3: %s', 'amazon-s3-and-cloudfront' ), $s3_object['key'], $e->getMessage() ) );
635
 
636
  return false;
637
  }
@@ -841,6 +889,46 @@ class AS3CF_Plugin_Compatibility {
841
  return $image;
842
  }
843
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
844
  /**
845
  * Replace local URLs with S3 ones for srcset image sources
846
  *
@@ -853,6 +941,11 @@ class AS3CF_Plugin_Compatibility {
853
  * @return array
854
  */
855
  public function wp_calculate_image_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id ) {
 
 
 
 
 
856
  if ( ! ( $s3object = $this->as3cf->get_attachment_s3_info( $attachment_id ) ) ) {
857
  // Attachment not uploaded to S3, abort
858
  return $sources;
33
  */
34
  protected static $stream_wrappers = array();
35
 
36
+ /**
37
+ * @var array
38
+ */
39
+ protected $compatibility_addons;
40
+
41
  /**
42
  * @param Amazon_S3_And_CloudFront $as3cf
43
  */
58
  add_filter( 'attachment_url_to_postid', array( $this, 'customizer_background_image' ), 10, 2 );
59
 
60
  /*
61
+ * Responsive Images WP 4.4
62
  */
63
+ add_filter( 'wp_calculate_image_srcset', array( $this, 'wp_calculate_image_srcset' ), 10, 5 );
64
+
65
  global $wp_version;
66
  if ( 0 === version_compare( $wp_version, '4.4' ) ) {
67
+ // Hot fix for 4.4
68
  add_filter( 'the_content', array( $this, 'wp_make_content_images_responsive' ), 11 );
69
  }
70
 
71
+ /*
72
+ * Responsive Images WP 4.4.1+
73
+ */
74
+ add_filter( 'wp_calculate_image_srcset_meta', array( $this, 'wp_calculate_image_srcset_meta' ), 10, 4 );
75
 
76
  if ( $this->as3cf->is_plugin_setup() ) {
77
  $this->compatibility_init_if_setup();
120
  global $amazon_web_services;
121
 
122
  $all_addons = $amazon_web_services->get_addons( true );
123
+ if ( ! isset( $all_addons['amazon-s3-and-cloudfront-pro']['addons'] ) ) {
124
  return array();
125
  }
126
 
127
+ $addons = $all_addons['amazon-s3-and-cloudfront-pro']['addons'];
128
 
129
  return $addons;
130
  }
135
  * @return array
136
  */
137
  public function get_compatibility_addons_to_install() {
138
+ if ( isset( $this->compatibility_addons ) ) {
139
+ return $this->compatibility_addons;
140
+ }
141
 
142
+ $addons = $this->get_pro_addons();
143
  $addons_to_install = array();
144
 
145
  if ( empty ( $addons ) ) {
168
  );
169
  }
170
 
171
+ $this->compatibility_addons = $addons_to_install;
172
+
173
  return $addons_to_install;
174
  }
175
 
188
  return;
189
  }
190
 
191
+ if ( ! $this->should_show_compatibility_notice() ) {
192
+ // No addons to install, or addons haven't changed
 
 
 
 
 
193
  return;
194
  }
195
 
196
+ $notice_id = 'as3cf-compat-addons';
197
+ $addons_to_install = $this->get_compatibility_addons_to_install();
198
+
199
+ // Remove previous notice to refresh addon list
200
+ $this->remove_compatibility_notice();
201
+
202
  $title = __( 'WP Offload S3 Compatibility Addons', 'amazon-s3-and-cloudfront' );
203
  $compat_url = 'https://deliciousbrains.com/wp-offload-s3/doc/compatibility-with-other-plugins/';
204
  $compat_link = sprintf( '<a href="%s">%s</a>', $compat_url, __( 'compatibility addons', 'amazon-s3-and-cloudfront' ) );
236
  }
237
 
238
  /**
239
+ * Should show compatibility notice
 
240
  *
241
+ * @return bool
 
242
  */
243
+ protected function should_show_compatibility_notice() {
244
+ $addons = $this->get_compatibility_addons_to_install();
245
+ $previous_addons = get_site_option( 'as3cf_compat_addons_to_install', array() );
246
 
247
+ if ( empty( $addons ) && empty( $previous_addons ) ) {
248
+ // No addons to install
249
+ return false;
250
  }
251
 
252
+ if ( empty( $addons ) && ! empty( $previous_addons ) ) {
253
+ // No addons to install but previous exist
254
+ $this->remove_compatibility_notice( true );
255
 
256
+ return false;
257
+ }
258
+
259
+ if ( $previous_addons === $addons ) {
260
+ // Addons have not changed
261
+ return false;
262
+ }
263
+
264
+ return true;
265
+ }
266
+
267
+ /**
268
+ * Remove compatibility notice
269
+ *
270
+ * @param bool $delete_option
271
+ */
272
+ protected function remove_compatibility_notice( $delete_option = false ) {
273
+ $notice_id = 'as3cf-compat-addons';
274
+
275
+ if ( $this->as3cf->notices->find_notice_by_id( $notice_id ) ) {
276
  $this->as3cf->notices->undismiss_notice_for_all( $notice_id );
277
+ $this->as3cf->notices->remove_notice_by_id( $notice_id );
278
  }
279
 
280
+ if ( $delete_option ) {
281
+ delete_site_option( 'as3cf_compat_addons_to_install' );
282
+ }
283
  }
284
 
285
  /**
365
  $var_type = 'GET';
366
 
367
  if ( isset( $_GET['action'] ) ) {
368
+ $action = $this->as3cf->filter_input( 'action' );
369
  } else if ( isset( $_POST['action'] ) ) {
370
  $var_type = 'POST';
371
+ $action = $this->as3cf->filter_input( 'action', INPUT_POST );
372
  } else {
373
  return false;
374
  }
376
  $context_check = true;
377
  if ( ! is_null( $context_key ) ) {
378
  $global = constant( 'INPUT_' . $var_type );
379
+ $context = $this->as3cf->filter_input( 'context', $global );
380
  $context_check = ( $context_key === $context );
381
  }
382
 
660
  *
661
  * @return string|bool File if downloaded, false on failure
662
  */
663
+ public function copy_s3_file_to_server( $s3_object, $file ) {
664
+ // Make sure the directory exists
665
+ $dir = dirname( $file );
666
+ if ( ! wp_mkdir_p( $dir ) ) {
667
+ $error_message = sprintf( __( 'The local directory %s does not exist and could not be created.', 'amazon-s3-and-cloudfront' ), $dir );
668
+ AS3CF_Error::log( sprintf( __( 'There was an error attempting to download the file %s from S3: %s', 'amazon-s3-and-cloudfront' ), $s3_object['key'], $error_message ) );
669
+
670
+ return false;
671
+ }
672
+
673
  try {
674
  $this->as3cf->get_s3client( $s3_object['region'], true )->getObject(
675
  array(
679
  )
680
  );
681
  } catch ( Exception $e ) {
682
+ AS3CF_Error::log( sprintf( __( 'There was an error attempting to download the file %s from S3: %s', 'amazon-s3-and-cloudfront' ), $s3_object['key'], $e->getMessage() ) );
683
 
684
  return false;
685
  }
889
  return $image;
890
  }
891
 
892
+ /**
893
+ * Alter the image meta data to add srcset support for object versioned S3 URLs
894
+ *
895
+ * @param array $image_meta
896
+ * @param array $size_array
897
+ * @param string $image_src
898
+ * @param int $attachment_id
899
+ *
900
+ * @return array
901
+ */
902
+ public function wp_calculate_image_srcset_meta( $image_meta, $size_array, $image_src, $attachment_id ) {
903
+ if ( empty( $image_meta['file'] ) ) {
904
+ // Corrupt `_wp_attachment_metadata`
905
+ return $image_meta;
906
+ }
907
+
908
+ if ( false !== strpos( $image_src, $image_meta['file'] ) ) {
909
+ // Path matches URL, no need to change
910
+ return $image_meta;
911
+ }
912
+
913
+ if ( ! ( $s3object = $this->as3cf->get_attachment_s3_info( $attachment_id ) ) ) {
914
+ // Attachment not uploaded to S3, abort
915
+ return $image_meta;
916
+ }
917
+
918
+ $image_basename = wp_basename( $image_meta['file'] );
919
+
920
+ if ( false === strpos( $s3object['key'], $image_basename ) ) {
921
+ // Not the correct attachment, abort
922
+ return $image_meta;
923
+ }
924
+
925
+ // Strip the meta file prefix so the just the filename will always match
926
+ // the S3 URL regardless of different prefixes for the offloaded file
927
+ $image_meta['file'] = $image_basename;
928
+
929
+ return $image_meta;
930
+ }
931
+
932
  /**
933
  * Replace local URLs with S3 ones for srcset image sources
934
  *
941
  * @return array
942
  */
943
  public function wp_calculate_image_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id ) {
944
+ if ( ! is_array( $sources ) ) {
945
+ // Sources corrupt
946
+ return $sources;
947
+ }
948
+
949
  if ( ! ( $s3object = $this->as3cf->get_attachment_s3_info( $attachment_id ) ) ) {
950
  // Attachment not uploaded to S3, abort
951
  return $sources;
classes/as3cf-upgrade.php CHANGED
@@ -124,19 +124,21 @@ abstract class AS3CF_Upgrade {
124
  }
125
 
126
  // If the upgrade status is already set, then we've already initialized the upgrade
127
- if ( $this->get_upgrade_status() ) {
 
 
 
 
128
  return false;
129
  }
130
 
131
  // Have we completed the upgrade?
132
- if ( $this->as3cf->get_setting( $this->settings_key, 0 ) >= $this->upgrade_id ) {
133
  return false;
134
  }
135
 
136
  // Has the previous upgrade completed yet?
137
- $previous_id = $this->upgrade_id - 1;
138
- if ( 0 !== $previous_id && (int) $this->as3cf->get_setting( $this->settings_key, 0 ) < $previous_id ) {
139
- // Previous still running, abort
140
  return false;
141
  }
142
 
@@ -177,7 +179,7 @@ abstract class AS3CF_Upgrade {
177
  // Initialize the upgrade
178
  $this->save_session( array( 'status' => self::STATUS_RUNNING ) );
179
 
180
- $this->as3cf->schedule_event( $this->cron_hook, $this->cron_schedule_key );
181
  }
182
 
183
  /**
@@ -185,8 +187,8 @@ abstract class AS3CF_Upgrade {
185
  */
186
  function do_upgrade() {
187
  // Check if the cron should even be running
188
- if ( $this->as3cf->get_setting( $this->settings_key, 0 ) >= $this->upgrade_id || $this->get_upgrade_status() !== self::STATUS_RUNNING ) {
189
- $this->as3cf->clear_scheduled_event( $this->cron_hook );
190
 
191
  return;
192
  }
@@ -254,12 +256,14 @@ abstract class AS3CF_Upgrade {
254
 
255
  if ( time() >= $finish || $this->as3cf->memory_exceeded( 'as3cf_update_' . $this->upgrade_name . '_memory_exceeded' ) ) {
256
  // Batch limits reached
 
 
257
  break 2;
258
  }
259
  }
260
- }
261
 
262
- $this->as3cf->restore_current_blog( $blog_id );
 
263
 
264
  $session['processed_blog_ids'] = $processed_blog_ids;
265
  $session['error_count'] = $this->error_count;
@@ -307,7 +311,15 @@ abstract class AS3CF_Upgrade {
307
  * Handler for the running upgrade actions
308
  */
309
  function maybe_handle_action() {
310
- if ( ! isset( $_GET['page'] ) || sanitize_key( $_GET['page'] ) !== $this->as3cf->get_plugin_slug() || ! isset( $_GET['action'] ) ) { // input var okay
 
 
 
 
 
 
 
 
311
  return;
312
  }
313
 
@@ -325,7 +337,7 @@ abstract class AS3CF_Upgrade {
325
  function upgrade_error( $session ) {
326
  $session['status'] = self::STATUS_ERROR;
327
  $this->save_session( $session );
328
- $this->as3cf->clear_scheduled_event( $this->cron_hook );
329
  }
330
 
331
  /**
@@ -333,20 +345,15 @@ abstract class AS3CF_Upgrade {
333
  */
334
  function upgrade_finished() {
335
  $this->clear_session();
336
- $this->as3cf->set_setting( $this->settings_key, $this->upgrade_id );
337
- $this->as3cf->save_settings();
338
- $this->as3cf->clear_scheduled_event( $this->cron_hook );
339
  }
340
 
341
  /**
342
  * Restart upgrade
343
  */
344
  function action_restart_update() {
345
- if ( ! isset( $_GET['update'] ) || $this->upgrade_name !== sanitize_key( $_GET['update'] ) ) {
346
- return;
347
- }
348
-
349
- $this->as3cf->schedule_event( $this->cron_hook, $this->cron_schedule_key );
350
  $this->change_status_request( self::STATUS_RUNNING );
351
  }
352
 
@@ -354,11 +361,7 @@ abstract class AS3CF_Upgrade {
354
  * Pause upgrade
355
  */
356
  function action_pause_update() {
357
- if ( ! isset( $_GET['update'] ) || $this->upgrade_name !== sanitize_key( $_GET['update'] ) ) {
358
- return;
359
- }
360
-
361
- $this->as3cf->clear_scheduled_event( $this->cron_hook );
362
  $this->change_status_request( self::STATUS_PAUSED );
363
  }
364
 
@@ -377,6 +380,20 @@ abstract class AS3CF_Upgrade {
377
  exit;
378
  }
379
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
380
  /**
381
  * Add custom cron interval schedules
382
  *
@@ -433,4 +450,37 @@ abstract class AS3CF_Upgrade {
433
  function clear_session() {
434
  delete_site_option( 'update_' . $this->upgrade_name . '_session' );
435
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
  }
124
  }
125
 
126
  // If the upgrade status is already set, then we've already initialized the upgrade
127
+ if ( $upgrade_status = $this->get_upgrade_status() ) {
128
+ if ( self::STATUS_RUNNING === $upgrade_status ) {
129
+ // Make sure cron job is persisted in case it has dropped
130
+ $this->schedule();
131
+ }
132
  return false;
133
  }
134
 
135
  // Have we completed the upgrade?
136
+ if ( $this->get_saved_upgrade_id() >= $this->upgrade_id ) {
137
  return false;
138
  }
139
 
140
  // Has the previous upgrade completed yet?
141
+ if ( ! $this->has_previous_upgrade_completed() ) {
 
 
142
  return false;
143
  }
144
 
179
  // Initialize the upgrade
180
  $this->save_session( array( 'status' => self::STATUS_RUNNING ) );
181
 
182
+ $this->schedule();
183
  }
184
 
185
  /**
187
  */
188
  function do_upgrade() {
189
  // Check if the cron should even be running
190
+ if ( $this->get_saved_upgrade_id() >= $this->upgrade_id || $this->get_upgrade_status() !== self::STATUS_RUNNING ) {
191
+ $this->unschedule();
192
 
193
  return;
194
  }
256
 
257
  if ( time() >= $finish || $this->as3cf->memory_exceeded( 'as3cf_update_' . $this->upgrade_name . '_memory_exceeded' ) ) {
258
  // Batch limits reached
259
+ $this->as3cf->restore_current_blog();
260
+
261
  break 2;
262
  }
263
  }
 
264
 
265
+ $this->as3cf->restore_current_blog();
266
+ }
267
 
268
  $session['processed_blog_ids'] = $processed_blog_ids;
269
  $session['error_count'] = $this->error_count;
311
  * Handler for the running upgrade actions
312
  */
313
  function maybe_handle_action() {
314
+ if ( ! isset( $_GET['page'] ) || sanitize_key( $_GET['page'] ) !== $this->as3cf->get_plugin_slug() ) { // input var okay
315
+ return;
316
+ }
317
+
318
+ if ( ! isset( $_GET['action'] ) ) {
319
+ return;
320
+ }
321
+
322
+ if ( ! isset( $_GET['update'] ) || sanitize_key( $_GET['update'] ) !== $this->upgrade_name ) { // input var okay
323
  return;
324
  }
325
 
337
  function upgrade_error( $session ) {
338
  $session['status'] = self::STATUS_ERROR;
339
  $this->save_session( $session );
340
+ $this->unschedule();
341
  }
342
 
343
  /**
345
  */
346
  function upgrade_finished() {
347
  $this->clear_session();
348
+ $this->update_saved_upgrade_id();
349
+ $this->unschedule();
 
350
  }
351
 
352
  /**
353
  * Restart upgrade
354
  */
355
  function action_restart_update() {
356
+ $this->schedule();
 
 
 
 
357
  $this->change_status_request( self::STATUS_RUNNING );
358
  }
359
 
361
  * Pause upgrade
362
  */
363
  function action_pause_update() {
364
+ $this->unschedule();
 
 
 
 
365
  $this->change_status_request( self::STATUS_PAUSED );
366
  }
367
 
380
  exit;
381
  }
382
 
383
+ /**
384
+ * Schedule the cron
385
+ */
386
+ function schedule() {
387
+ $this->as3cf->schedule_event( $this->cron_hook, $this->cron_schedule_key );
388
+ }
389
+
390
+ /**
391
+ * Remove the cron schedule
392
+ */
393
+ function unschedule() {
394
+ $this->as3cf->clear_scheduled_event( $this->cron_hook );
395
+ }
396
+
397
  /**
398
  * Add custom cron interval schedules
399
  *
450
  function clear_session() {
451
  delete_site_option( 'update_' . $this->upgrade_name . '_session' );
452
  }
453
+
454
+ /**
455
+ * Get the saved upgrade ID
456
+ *
457
+ * @return int|mixed|string|WP_Error
458
+ */
459
+ function get_saved_upgrade_id() {
460
+ return $this->as3cf->get_setting( $this->settings_key, 0 );
461
+ }
462
+
463
+ /**
464
+ * Update the saved upgrade ID
465
+ */
466
+ function update_saved_upgrade_id() {
467
+ $this->as3cf->set_setting( $this->settings_key, $this->upgrade_id );
468
+ $this->as3cf->save_settings();
469
+ }
470
+
471
+ /**
472
+ * Has previous upgrade completed
473
+ *
474
+ * @return bool
475
+ */
476
+ function has_previous_upgrade_completed() {
477
+ // Has the previous upgrade completed yet?
478
+ $previous_id = $this->upgrade_id - 1;
479
+ if ( 0 !== $previous_id && (int) $this->get_saved_upgrade_id() < $previous_id ) {
480
+ // Previous still running, abort
481
+ return false;
482
+ }
483
+
484
+ return true;
485
+ }
486
  }
classes/as3cf-utils.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin Utilities
4
+ *
5
+ * @package amazon-s3-and-cloudfront
6
+ * @subpackage Classes/Utils
7
+ * @copyright Copyright (c) 2015, Delicious Brains
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ */
10
+
11
+ // Exit if accessed directly
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+
16
+ if ( ! class_exists( 'AS3CF_Utils' ) ) {
17
+
18
+ /**
19
+ * AS3CF_Utils Class
20
+ *
21
+ * This class contains utility functions that need to be available
22
+ * across the Pro plugin codebase
23
+ *
24
+ */
25
+ class AS3CF_Utils {
26
+
27
+ /**
28
+ * Checks if another version of WP Offload S3 (Lite) is active and deactivates it.
29
+ * To be hooked on `activated_plugin` so other plugin is deactivated when current plugin is activated.
30
+ *
31
+ * @param string $plugin
32
+ *
33
+ * @return bool
34
+ */
35
+ public static function deactivate_other_instances( $plugin ) {
36
+ if ( ! in_array( basename( $plugin ), array( 'amazon-s3-and-cloudfront-pro.php', 'wordpress-s3.php' ) ) ) {
37
+ return false;
38
+ }
39
+
40
+ $plugin_to_deactivate = 'wordpress-s3.php';
41
+ $deactivated_notice_id = '1';
42
+ if ( basename( $plugin ) === $plugin_to_deactivate ) {
43
+ $plugin_to_deactivate = 'amazon-s3-and-cloudfront-pro.php';
44
+ $deactivated_notice_id = '2';
45
+ }
46
+
47
+ if ( is_multisite() ) {
48
+ $active_plugins = (array) get_site_option( 'active_sitewide_plugins', array() );
49
+ $active_plugins = array_keys( $active_plugins );
50
+ } else {
51
+ $active_plugins = (array) get_option( 'active_plugins', array() );
52
+ }
53
+
54
+ foreach ( $active_plugins as $basename ) {
55
+ if ( false !== strpos( $basename, $plugin_to_deactivate ) ) {
56
+ set_transient( 'as3cf_deactivated_notice_id', $deactivated_notice_id, HOUR_IN_SECONDS );
57
+ deactivate_plugins( $basename );
58
+
59
+ return true;
60
+ }
61
+ }
62
+
63
+ return false;
64
+ }
65
+ }
66
+ }
classes/upgrades/as3cf-file-sizes.php CHANGED
@@ -49,7 +49,7 @@ class AS3CF_Upgrade_File_Sizes extends AS3CF_Upgrade {
49
  function upgrade_attachment( $attachment ) {
50
  $s3object = unserialize( $attachment->s3object );
51
  if ( false === $s3object ) {
52
- error_log( 'Failed to unserialize S3 meta for attachment ' . $attachment->ID . ': ' . $attachment->s3object );
53
  $this->error_count++;
54
 
55
  return false;
@@ -57,7 +57,7 @@ class AS3CF_Upgrade_File_Sizes extends AS3CF_Upgrade {
57
 
58
  $region = $this->as3cf->get_s3object_region( $s3object );
59
  if ( is_wp_error( $region ) ) {
60
- error_log( 'Failed to get the region for the bucket of the attachment ' . $attachment->ID );
61
  $this->error_count++;
62
 
63
  return false;
@@ -81,7 +81,7 @@ class AS3CF_Upgrade_File_Sizes extends AS3CF_Upgrade {
81
  // List objects for the attachment
82
  $result = $s3client->ListObjects( $args );
83
  } catch ( Exception $e ) {
84
- error_log( 'Error listing objects of prefix ' . $search_prefix . ' for attachment ' . $attachment->ID . ' from S3: ' . $e->getMessage() );
85
  $this->error_count ++;
86
 
87
  return false;
@@ -107,7 +107,7 @@ class AS3CF_Upgrade_File_Sizes extends AS3CF_Upgrade {
107
  }
108
 
109
  if ( 0 === $file_size_total ) {
110
- error_log( 'Total file size for the attachment is 0: ' . $attachment->ID );
111
  $this->error_count ++;
112
 
113
  return false;
49
  function upgrade_attachment( $attachment ) {
50
  $s3object = unserialize( $attachment->s3object );
51
  if ( false === $s3object ) {
52
+ AS3CF_Error::log( 'Failed to unserialize S3 meta for attachment ' . $attachment->ID . ': ' . $attachment->s3object );
53
  $this->error_count++;
54
 
55
  return false;
57
 
58
  $region = $this->as3cf->get_s3object_region( $s3object );
59
  if ( is_wp_error( $region ) ) {
60
+ AS3CF_Error::log( 'Failed to get the region for the bucket of the attachment ' . $attachment->ID );
61
  $this->error_count++;
62
 
63
  return false;
81
  // List objects for the attachment
82
  $result = $s3client->ListObjects( $args );
83
  } catch ( Exception $e ) {
84
+ AS3CF_Error::log( 'Error listing objects of prefix ' . $search_prefix . ' for attachment ' . $attachment->ID . ' from S3: ' . $e->getMessage() );
85
  $this->error_count ++;
86
 
87
  return false;
107
  }
108
 
109
  if ( 0 === $file_size_total ) {
110
+ AS3CF_Error::log( 'Total file size for the attachment is 0: ' . $attachment->ID );
111
  $this->error_count ++;
112
 
113
  return false;
classes/upgrades/as3cf-meta-wp-error.php CHANGED
@@ -50,7 +50,7 @@ class AS3CF_Upgrade_Meta_WP_Error extends AS3CF_Upgrade {
50
  function upgrade_attachment( $attachment ) {
51
  $s3object = unserialize( $attachment->s3object );
52
  if ( false === $s3object ) {
53
- error_log( 'Failed to unserialize S3 meta for attachment ' . $attachment->ID . ': ' . $attachment->s3object );
54
  $this->error_count++;
55
 
56
  return false;
@@ -69,7 +69,7 @@ class AS3CF_Upgrade_Meta_WP_Error extends AS3CF_Upgrade {
69
  );
70
  $this->as3cf->get_s3client( $s3object['region'], true )->getObject( $args );
71
  } catch ( Exception $e ) {
72
- error_log( sprintf( __( 'There was an error attempting to download the file %s from S3: %s', 'amazon-s3-and-cloudfront' ), $s3object['key'], $e->getMessage() ) );
73
 
74
  return false;
75
  }
50
  function upgrade_attachment( $attachment ) {
51
  $s3object = unserialize( $attachment->s3object );
52
  if ( false === $s3object ) {
53
+ AS3CF_Error::log( 'Failed to unserialize S3 meta for attachment ' . $attachment->ID . ': ' . $attachment->s3object );
54
  $this->error_count++;
55
 
56
  return false;
69
  );
70
  $this->as3cf->get_s3client( $s3object['region'], true )->getObject( $args );
71
  } catch ( Exception $e ) {
72
+ AS3CF_Error::log( sprintf( __( 'There was an error attempting to download the file %s from S3: %s', 'amazon-s3-and-cloudfront' ), $s3object['key'], $e->getMessage() ) );
73
 
74
  return false;
75
  }
classes/upgrades/as3cf-region-meta.php CHANGED
@@ -48,7 +48,7 @@ class AS3CF_Upgrade_Region_Meta extends AS3CF_Upgrade {
48
  function upgrade_attachment( $attachment ) {
49
  $s3object = unserialize( $attachment->s3object );
50
  if ( false === $s3object ) {
51
- error_log( 'Failed to unserialize S3 meta for attachment ' . $attachment->ID . ': ' . $attachment->s3object );
52
  $this->error_count++;
53
 
54
  return false;
@@ -56,7 +56,7 @@ class AS3CF_Upgrade_Region_Meta extends AS3CF_Upgrade {
56
  // retrieve region and update the attachment metadata
57
  $region = $this->as3cf->get_s3object_region( $s3object, $attachment->ID );
58
  if ( is_wp_error( $region ) ) {
59
- error_log( 'Error updating region: ' . $region->get_error_message() );
60
  $this->error_count++;
61
 
62
  return false;
48
  function upgrade_attachment( $attachment ) {
49
  $s3object = unserialize( $attachment->s3object );
50
  if ( false === $s3object ) {
51
+ AS3CF_Error::log( 'Failed to unserialize S3 meta for attachment ' . $attachment->ID . ': ' . $attachment->s3object );
52
  $this->error_count++;
53
 
54
  return false;
56
  // retrieve region and update the attachment metadata
57
  $region = $this->as3cf->get_s3object_region( $s3object, $attachment->ID );
58
  if ( is_wp_error( $region ) ) {
59
+ AS3CF_Error::log( 'Error updating region: ' . $region->get_error_message() );
60
  $this->error_count++;
61
 
62
  return false;
classes/wp-aws-compatibility-check.php CHANGED
@@ -30,7 +30,7 @@ if ( ! class_exists( 'WP_AWS_Compatibility_Check' ) ) {
30
  protected $plugin_slug;
31
 
32
  /**
33
- * @var string The name of the plugin, e.g. WP Offload S3 - Pro Upgrade
34
  */
35
  protected $plugin_name;
36
 
@@ -123,6 +123,19 @@ if ( ! class_exists( 'WP_AWS_Compatibility_Check' ) ) {
123
  return $compatible;
124
  }
125
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  /**
127
  * Get the basename for the plugin
128
  *
30
  protected $plugin_slug;
31
 
32
  /**
33
+ * @var string The name of the plugin, e.g. WP Offload S3
34
  */
35
  protected $plugin_name;
36
 
123
  return $compatible;
124
  }
125
 
126
+ /**
127
+ * Is a plugin active
128
+ *
129
+ * @param string $plugin_base
130
+ *
131
+ * @return bool
132
+ */
133
+ function is_plugin_active( $plugin_base ) {
134
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
135
+
136
+ return is_plugin_active( $plugin_base );
137
+ }
138
+
139
  /**
140
  * Get the basename for the plugin
141
  *
classes/wp-aws-uninstall.php CHANGED
@@ -53,6 +53,11 @@ if ( ! class_exists( 'WP_AWS_Uninstall' ) ) {
53
  */
54
  protected $transients;
55
 
 
 
 
 
 
56
  /**
57
  * @var array Blog(s) in site
58
  */
@@ -65,17 +70,20 @@ if ( ! class_exists( 'WP_AWS_Uninstall' ) ) {
65
  * @param array|string $postmeta
66
  * @param array|string $crons
67
  * @param array|string $transients
 
68
  */
69
  public function __construct(
70
  $options = array(),
71
  $postmeta = array(),
72
  $crons = array(),
73
- $transients = array()
 
74
  ) {
75
  $this->options = $this->maybe_convert_to_array( $options );
76
  $this->postmeta = $this->maybe_convert_to_array( $postmeta );
77
  $this->crons = $this->maybe_convert_to_array( $crons );
78
  $this->transients = $this->maybe_convert_to_array( $transients );
 
79
 
80
  $this->set_blog_ids();
81
 
@@ -83,6 +91,7 @@ if ( ! class_exists( 'WP_AWS_Uninstall' ) ) {
83
  $this->delete_postmeta();
84
  $this->clear_crons();
85
  $this->delete_transients();
 
86
  }
87
 
88
  /**
@@ -201,17 +210,52 @@ if ( ! class_exists( 'WP_AWS_Uninstall' ) ) {
201
  $subsite_transients = $this->maybe_convert_to_array( $this->transients['subsite'] );
202
 
203
  foreach ( $this->blog_ids as $blog_id ) {
204
- if ( is_multisite() && ! $this->is_current_blog( $blog_id ) ) {
205
  switch_to_blog( $blog_id );
206
  }
207
 
208
  foreach ( $subsite_transients as $transient ) {
209
  delete_transient( $transient );
210
  }
 
 
 
 
211
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
 
213
- if ( is_multisite() && ! $this->is_current_blog( $blog_id ) ) {
214
- restore_current_blog();
 
 
215
  }
216
  }
217
  }
53
  */
54
  protected $transients;
55
 
56
+ /**
57
+ * @var array|string User meta to be deleted
58
+ */
59
+ protected $usermeta;
60
+
61
  /**
62
  * @var array Blog(s) in site
63
  */
70
  * @param array|string $postmeta
71
  * @param array|string $crons
72
  * @param array|string $transients
73
+ * @param array|string $usermeta
74
  */
75
  public function __construct(
76
  $options = array(),
77
  $postmeta = array(),
78
  $crons = array(),
79
+ $transients = array(),
80
+ $usermeta = array()
81
  ) {
82
  $this->options = $this->maybe_convert_to_array( $options );
83
  $this->postmeta = $this->maybe_convert_to_array( $postmeta );
84
  $this->crons = $this->maybe_convert_to_array( $crons );
85
  $this->transients = $this->maybe_convert_to_array( $transients );
86
+ $this->usermeta = $this->maybe_convert_to_array( $usermeta );
87
 
88
  $this->set_blog_ids();
89
 
91
  $this->delete_postmeta();
92
  $this->clear_crons();
93
  $this->delete_transients();
94
+ $this->delete_usermeta();
95
  }
96
 
97
  /**
210
  $subsite_transients = $this->maybe_convert_to_array( $this->transients['subsite'] );
211
 
212
  foreach ( $this->blog_ids as $blog_id ) {
213
+ if ( is_multisite() && $blog_id !== get_current_blog_id() ) {
214
  switch_to_blog( $blog_id );
215
  }
216
 
217
  foreach ( $subsite_transients as $transient ) {
218
  delete_transient( $transient );
219
  }
220
+
221
+ if ( is_multisite() ) {
222
+ restore_current_blog();
223
+ }
224
  }
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Delete user meta.
230
+ */
231
+ public function delete_usermeta() {
232
+ global $wpdb;
233
+
234
+ if ( empty( $this->usermeta ) ) {
235
+ return;
236
+ }
237
+
238
+ // Loop through our user meta keys to create our WHERE clauses.
239
+ $where_array = array();
240
+ foreach ( $this->usermeta as $usermeta ) {
241
+ $where_array[] = $wpdb->prepare( "meta_key = '%s'", $usermeta );
242
+ }
243
+
244
+ // Merge all WHERE clauses into an OR comparison.
245
+ $where_sql = implode( ' OR ', $where_array );
246
+
247
+ // Get any user ids that have keys to be deleted.
248
+ $user_ids = $wpdb->get_col( "SELECT DISTINCT user_id FROM {$wpdb->usermeta} WHERE {$where_sql}" );
249
+
250
+ // Bail if no user has keys to be deleted.
251
+ if ( empty( $user_ids ) ) {
252
+ return;
253
+ }
254
 
255
+ // Loop through the list of users and delete our user meta.
256
+ foreach ( $user_ids as $user_id ) {
257
+ foreach ( $this->usermeta as $usermeta ) {
258
+ delete_user_meta( $user_id, $usermeta );
259
  }
260
  }
261
  }
languages/amazon-s3-and-cloudfront-en.pot CHANGED
@@ -8,7 +8,7 @@ msgid ""
8
  msgstr ""
9
  "Project-Id-Version: amazon-s3-and-cloudfront\n"
10
  "Report-Msgid-Bugs-To: nom@deliciousbrains.com\n"
11
- "POT-Creation-Date: 2015-12-19 11:14+0000\n"
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,132 +17,139 @@ msgstr ""
17
  "Content-Type: text/plain; charset=UTF-8\n"
18
  "Content-Transfer-Encoding: 8bit\n"
19
 
20
- #: classes/amazon-s3-and-cloudfront.php:100
21
- msgid "Offload S3"
22
  msgstr ""
23
 
24
- #: classes/amazon-s3-and-cloudfront.php:101
25
  msgid "S3 and CloudFront"
26
  msgstr ""
27
 
28
- #: classes/amazon-s3-and-cloudfront.php:567
 
 
 
 
 
29
  msgid "Upload aborted by filter 'as3cf_pre_upload_attachment'"
30
  msgstr ""
31
 
32
- #: classes/amazon-s3-and-cloudfront.php:578
33
  #, php-format
34
  msgid "File %s does not exist"
35
  msgstr ""
36
 
37
- #: classes/amazon-s3-and-cloudfront.php:589
38
  #, php-format
39
  msgid "Mime type %s is not allowed"
40
  msgstr ""
41
 
42
- #: classes/amazon-s3-and-cloudfront.php:670
43
  #, php-format
44
  msgid "Error uploading %s to S3: %s"
45
  msgstr ""
46
 
47
- #: classes/amazon-s3-and-cloudfront.php:1608
48
  msgid "Cheatin&#8217; eh?"
49
  msgstr ""
50
 
51
- #: classes/amazon-s3-and-cloudfront.php:1612
52
  msgid "You do not have sufficient permissions to access this page."
53
  msgstr ""
54
 
55
- #: classes/amazon-s3-and-cloudfront.php:1618
56
  msgid "No bucket name provided."
57
  msgstr ""
58
 
59
- #: classes/amazon-s3-and-cloudfront.php:1903
60
  msgid "Error Getting Bucket Region"
61
  msgstr ""
62
 
63
- #: classes/amazon-s3-and-cloudfront.php:1904
64
  #, php-format
65
  msgid "There was an error attempting to get the region of the bucket %s: %s"
66
  msgstr ""
67
 
68
- #: classes/amazon-s3-and-cloudfront.php:2024
69
  msgid ""
70
  "This is a test file to check if the user has write permission to S3. Delete "
71
  "me if found."
72
  msgstr ""
73
 
74
- #: classes/amazon-s3-and-cloudfront.php:2056
75
  #, php-format
76
  msgid ""
77
  "There was an error attempting to check the permissions of the bucket %s: %s"
78
  msgstr ""
79
 
80
- #: classes/amazon-s3-and-cloudfront.php:2113
81
  msgid "Error creating bucket"
82
  msgstr ""
83
 
84
- #: classes/amazon-s3-and-cloudfront.php:2114
85
  msgid "Bucket name too short."
86
  msgstr ""
87
 
88
- #: classes/amazon-s3-and-cloudfront.php:2115
89
  msgid "Bucket name too long."
90
  msgstr ""
91
 
92
- #: classes/amazon-s3-and-cloudfront.php:2116
93
  msgid ""
94
  "Invalid character. Bucket names can contain lowercase letters, numbers, "
95
  "periods and hyphens."
96
  msgstr ""
97
 
98
- #: classes/amazon-s3-and-cloudfront.php:2117
99
  msgid "Error saving bucket"
100
  msgstr ""
101
 
102
- #: classes/amazon-s3-and-cloudfront.php:2118
103
  msgid "Error fetching buckets"
104
  msgstr ""
105
 
106
- #: classes/amazon-s3-and-cloudfront.php:2119
107
  msgid "Error getting URL preview: "
108
  msgstr ""
109
 
110
- #: classes/amazon-s3-and-cloudfront.php:2120
111
  msgid "The changes you made will be lost if you navigate away from this page"
112
  msgstr ""
113
 
114
- #: classes/amazon-s3-and-cloudfront.php:2180
115
  msgid "Cheatin' eh?"
116
  msgstr ""
117
 
118
- #: classes/amazon-s3-and-cloudfront.php:2283
119
  msgctxt "Show the media library tab"
120
  msgid "Media Library"
121
  msgstr ""
122
 
123
- #: classes/amazon-s3-and-cloudfront.php:2284
124
  msgctxt "Show the support tab"
125
  msgid "Support"
126
  msgstr ""
127
 
128
- #: classes/amazon-s3-and-cloudfront.php:2436
129
  #, php-format
130
- msgid "The file %s has been given %s permissions on Amazon S3."
 
 
131
  msgstr ""
132
 
133
- #: classes/amazon-s3-and-cloudfront.php:2448
134
  msgid ""
135
- "<strong>Image Manipulation Library Missing</strong> &mdash; Looks like you "
136
  "don't have an image manipulation library installed on this server and "
137
  "configured with PHP. You may run into trouble if you try to edit images. "
138
  "Please setup GD or ImageMagick."
139
  msgstr ""
140
 
141
- #: classes/amazon-s3-and-cloudfront.php:2978
142
  msgid "Quick Start Guide"
143
  msgstr ""
144
 
145
- #: classes/amazon-s3-and-cloudfront.php:2980
146
  #, php-format
147
  msgid ""
148
  "Looks like we don't have write access to this bucket. It's likely that the "
@@ -151,7 +158,7 @@ msgid ""
151
  "correctly."
152
  msgstr ""
153
 
154
- #: classes/amazon-s3-and-cloudfront.php:2982
155
  #, php-format
156
  msgid ""
157
  "Looks like we don't have access to the buckets. It's likely that the user "
@@ -159,23 +166,64 @@ msgid ""
159
  "Please see our %s for instructions on setting up permissions correctly."
160
  msgstr ""
161
 
162
- #: classes/as3cf-notices.php:374
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  msgid "Error dismissing notice."
164
  msgstr ""
165
 
166
- #: classes/as3cf-notices.php:389
167
  msgid "Invalid notice ID."
168
  msgstr ""
169
 
170
- #: classes/as3cf-plugin-compatibility.php:185
171
  msgid "WP Offload S3 Compatibility Addons"
172
  msgstr ""
173
 
174
- #: classes/as3cf-plugin-compatibility.php:187
175
  msgid "compatibility addons"
176
  msgstr ""
177
 
178
- #: classes/as3cf-plugin-compatibility.php:188
179
  #, php-format
180
  msgid ""
181
  "To get WP Offload S3 to work with certain 3rd party plugins, you might need "
@@ -184,7 +232,7 @@ msgid ""
184
  "about each addon to determine if you need it or not."
185
  msgstr ""
186
 
187
- #: classes/as3cf-plugin-compatibility.php:194
188
  #, php-format
189
  msgid ""
190
  "You will need to purchase a license to get access to these addons. If you're "
@@ -192,17 +240,23 @@ msgid ""
192
  "to %s."
193
  msgstr ""
194
 
195
- #: classes/as3cf-plugin-compatibility.php:195
196
  msgid "View Licenses"
197
  msgstr ""
198
 
199
- #: classes/as3cf-plugin-compatibility.php:634
 
 
 
 
 
 
200
  #: classes/upgrades/as3cf-meta-wp-error.php:72
201
  #, php-format
202
  msgid "There was an error attempting to download the file %s from S3: %s"
203
  msgstr ""
204
 
205
- #: classes/as3cf-upgrade.php:279
206
  #, php-format
207
  msgid ""
208
  "<strong>Running %s Update</strong> &mdash; We&#8217;re going through all the "
@@ -212,22 +266,22 @@ msgid ""
212
  "performance."
213
  msgstr ""
214
 
215
- #: classes/as3cf-upgrade.php:280
216
  msgid "Pause Update"
217
  msgstr ""
218
 
219
- #: classes/as3cf-upgrade.php:284
220
  #, php-format
221
  msgid ""
222
  "<strong>%s Update Paused</strong> &mdash; Updating Media Library %s has been "
223
  "paused."
224
  msgstr ""
225
 
226
- #: classes/as3cf-upgrade.php:285
227
  msgid "Restart Update"
228
  msgstr ""
229
 
230
- #: classes/as3cf-upgrade.php:288
231
  #, php-format
232
  msgid ""
233
  "<strong>Error Updating %s</strong> &mdash; We ran into some errors "
@@ -235,11 +289,11 @@ msgid ""
235
  "uploaded to S3. Please check your error log for details. (#%d)"
236
  msgstr ""
237
 
238
- #: classes/as3cf-upgrade.php:289
239
  msgid "Try Run It Again"
240
  msgstr ""
241
 
242
- #: classes/as3cf-upgrade.php:391
243
  #, php-format
244
  msgid "Every %d Minutes"
245
  msgstr ""
@@ -263,79 +317,79 @@ msgid ""
263
  "style=\"white-space:nowrap;\">(e.g. s3-us-west-2.amazonaws.com)</span>."
264
  msgstr ""
265
 
266
- #: classes/wp-aws-compatibility-check.php:310
267
  msgid "deactivate"
268
  msgstr ""
269
 
270
- #: classes/wp-aws-compatibility-check.php:311
271
  #, php-format
272
  msgid "You can %s the %s plugin to get rid of this notice."
273
  msgstr ""
274
 
275
- #: classes/wp-aws-compatibility-check.php:314
276
  #, php-format
277
  msgid "%s has been disabled as it requires the %s plugin."
278
  msgstr ""
279
 
280
- #: classes/wp-aws-compatibility-check.php:318
281
  msgid "which is currently disabled."
282
  msgstr ""
283
 
284
- #: classes/wp-aws-compatibility-check.php:320
285
  msgid "It appears to be installed already."
286
  msgstr ""
287
 
288
- #: classes/wp-aws-compatibility-check.php:322
289
  msgctxt "Activate plugin"
290
  msgid "Activate it now."
291
  msgstr ""
292
 
293
- #: classes/wp-aws-compatibility-check.php:329
294
  #, php-format
295
  msgid "<a href=\"%s\">Install</a> and activate it."
296
  msgstr ""
297
 
298
- #: classes/wp-aws-compatibility-check.php:340
299
  #, php-format
300
  msgid ""
301
  "%s has been disabled as it requires version %s or later of the %s plugin."
302
  msgstr ""
303
 
304
- #: classes/wp-aws-compatibility-check.php:343
305
  #, php-format
306
  msgid "You currently have version %s installed."
307
  msgstr ""
308
 
309
- #: classes/wp-aws-compatibility-check.php:350
310
- #: classes/wp-aws-compatibility-check.php:388
311
  #, php-format
312
  msgid "A valid license for %s is required to update."
313
  msgstr ""
314
 
315
- #: classes/wp-aws-compatibility-check.php:358
316
  msgid "Update to the latest version"
317
  msgstr ""
318
 
319
- #: classes/wp-aws-compatibility-check.php:370
320
  #, php-format
321
  msgid ""
322
  "%1$s has been disabled because it is not a supported addon of the %2$s "
323
  "plugin."
324
  msgstr ""
325
 
326
- #: classes/wp-aws-compatibility-check.php:379
327
  #, php-format
328
  msgid ""
329
  "%1$s has been disabled because it will not work with the version of the %2$s "
330
  "plugin installed. %1$s %3$s or later is required."
331
  msgstr ""
332
 
333
- #: classes/wp-aws-compatibility-check.php:382
334
  #, php-format
335
  msgid "Update %s to the latest version"
336
  msgstr ""
337
 
338
- #: classes/wp-aws-compatibility-check.php:451
339
  #, php-format
340
  msgid "The %s plugin has been deactivated."
341
  msgstr ""
@@ -432,8 +486,9 @@ msgstr ""
432
  msgid "Change"
433
  msgstr ""
434
 
435
- #: view/bucket-setting.php:18
436
- msgid "(defined in wp-config.php)"
 
437
  msgstr ""
438
 
439
  #: view/debug-info.php:2
@@ -445,181 +500,170 @@ msgctxt "Download to your computer"
445
  msgid "Download"
446
  msgstr ""
447
 
448
- #: view/domain-setting.php:5
449
  msgid "Domain:"
450
  msgstr ""
451
 
452
- #: view/domain-setting.php:23
453
  msgid "Bucket name as subdomain"
454
  msgstr ""
455
 
456
- #: view/domain-setting.php:28
457
  msgid "Bucket name in path"
458
  msgstr ""
459
 
460
- #: view/domain-setting.php:33
461
  msgid "Bucket name as domain"
462
  msgstr ""
463
 
464
- #: view/domain-setting.php:38
465
  msgid "CloudFront or custom domain"
466
  msgstr ""
467
 
468
- #: view/domain-setting.php:42
469
- msgid "Invalid character. Letters, numbers, periods and hyphens are allowed."
 
 
 
 
 
 
470
  msgstr ""
471
 
472
  #: view/error-access.php:4
473
  msgid "Access Denied to Bucket"
474
  msgstr ""
475
 
 
 
 
 
 
 
 
 
476
  #: view/settings.php:10
477
  msgid "Settings saved."
478
  msgstr ""
479
 
480
- #: view/settings.php:46
481
  msgid "Enable/Disable the Plugin"
482
  msgstr ""
483
 
484
- #: view/settings.php:53
485
  msgid "Copy Files to S3"
486
  msgstr ""
487
 
488
- #: view/settings.php:54
489
  msgid ""
490
  "When a file is uploaded to the Media Library, copy it to S3. Existing files "
491
  "are <em>not</em> copied to S3."
492
  msgstr ""
493
 
494
- #: view/settings.php:62
495
  msgid "Rewrite File URLs"
496
  msgstr ""
497
 
498
- #: view/settings.php:63
499
  msgid ""
500
  "For Media Library files that have been copied to S3, rewrite the URLs so "
501
  "that they are served from S3/CloudFront instead of your server."
502
  msgstr ""
503
 
504
- #: view/settings.php:67
505
  msgid "Configure File URLs"
506
  msgstr ""
507
 
508
- #: view/settings.php:85
509
  msgid "Path"
510
  msgstr ""
511
 
512
- #: view/settings.php:87
513
- msgid "By default the path is the same as your local WordPress files:"
514
  msgstr ""
515
 
516
- #: view/settings.php:100
517
  msgid "Year/Month"
518
  msgstr ""
519
 
520
- #: view/settings.php:102
521
  msgid "Add the Year/Month in the URL."
522
  msgstr ""
523
 
524
- #: view/settings.php:108
525
- msgid "SSL:"
526
  msgstr ""
527
 
528
- #: view/settings.php:116
 
 
 
 
529
  msgid "Same as request"
530
  msgstr ""
531
 
532
- #: view/settings.php:117
533
  msgid "When the request is https://, use https:// for the file URL as well."
534
  msgstr ""
535
 
536
- #: view/settings.php:121
537
  msgid "Always SSL"
538
  msgstr ""
539
 
540
- #: view/settings.php:122
541
  msgid "Forces https:// to be used."
542
  msgstr ""
543
 
544
- #: view/settings.php:123
545
  msgid ""
546
  "You cannot use the \"Bucket as a subdomain\" domain option when using SSL."
547
  msgstr ""
548
 
549
- #: view/settings.php:127
550
  msgid "Always non-SSL"
551
  msgstr ""
552
 
553
- #: view/settings.php:128
554
  msgid "Forces http:// to be used."
555
  msgstr ""
556
 
557
- #: view/settings.php:134
558
  msgid "Advanced Options"
559
  msgstr ""
560
 
561
- #: view/settings.php:141
562
  msgid "Remove Files From Server"
563
  msgstr ""
564
 
565
- #: view/settings.php:142
566
  msgid "Once a file has been copied to S3, remove it from the local server."
567
  msgstr ""
568
 
569
- #: view/settings.php:144
570
  msgid ""
571
  "<strong>Broken URLs</strong> &mdash; There will be broken URLs for files "
572
  "that don't exist locally. You can fix this by enabling <strong>Rewrite File "
573
  "URLs</strong> to use the S3 URLs."
574
  msgstr ""
575
 
576
- #: view/settings.php:154
577
- #: view/settings.php:175
578
- #: view/settings.php:188
579
- msgid "More info"
580
- msgstr ""
581
-
582
- #: view/settings.php:155
583
  #, php-format
584
  msgid ""
585
  "<strong>Warning</strong> &mdash; Some plugins depend on the file being "
586
  "present on the local server and may not work when the file is removed. %s"
587
  msgstr ""
588
 
589
- #: view/settings.php:171
590
  msgid "Object Versioning"
591
  msgstr ""
592
 
593
- #: view/settings.php:173
594
  msgid ""
595
  "Append a timestamp to the S3 file path. Recommended when using CloudFront so "
596
  "you don't have to worry about cache invalidation."
597
  msgstr ""
598
 
599
- #: view/settings.php:185
600
- msgid "Far Future Expiration Header"
601
- msgstr ""
602
-
603
- #: view/settings.php:186
604
- msgid ""
605
- "Implements a \"Never Expire\" caching policy for browsers by setting an "
606
- "Expires header for 10 years in the future. Should be used in conjunction "
607
- "with object versioning above."
608
- msgstr ""
609
-
610
- #: view/settings.php:198
611
- msgid "Copy HiDPI (@2x) Images"
612
- msgstr ""
613
-
614
- #: view/settings.php:199
615
- #, php-format
616
- msgid ""
617
- "When uploading a file to S3, checks if there's a file of the same name with "
618
- "an @2x suffix and copies it to S3 as well. Works with the <a href=\"%s\">WP "
619
- "Retina 2x</a> plugin."
620
- msgstr ""
621
-
622
- #: view/settings.php:205
623
  msgid "Save Changes"
624
  msgstr ""
625
 
8
  msgstr ""
9
  "Project-Id-Version: amazon-s3-and-cloudfront\n"
10
  "Report-Msgid-Bugs-To: nom@deliciousbrains.com\n"
11
+ "POT-Creation-Date: 2016-03-07 16:48+0000\n"
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
17
  "Content-Type: text/plain; charset=UTF-8\n"
18
  "Content-Transfer-Encoding: 8bit\n"
19
 
20
+ #: classes/amazon-s3-and-cloudfront.php:101
21
+ msgid "Offload S3 Lite"
22
  msgstr ""
23
 
24
+ #: classes/amazon-s3-and-cloudfront.php:102
25
  msgid "S3 and CloudFront"
26
  msgstr ""
27
 
28
+ #: classes/amazon-s3-and-cloudfront.php:195
29
+ #: view/bucket-setting.php:18
30
+ msgid "defined in wp-config.php"
31
+ msgstr ""
32
+
33
+ #: classes/amazon-s3-and-cloudfront.php:769
34
  msgid "Upload aborted by filter 'as3cf_pre_upload_attachment'"
35
  msgstr ""
36
 
37
+ #: classes/amazon-s3-and-cloudfront.php:780
38
  #, php-format
39
  msgid "File %s does not exist"
40
  msgstr ""
41
 
42
+ #: classes/amazon-s3-and-cloudfront.php:791
43
  #, php-format
44
  msgid "Mime type %s is not allowed"
45
  msgstr ""
46
 
47
+ #: classes/amazon-s3-and-cloudfront.php:878
48
  #, php-format
49
  msgid "Error uploading %s to S3: %s"
50
  msgstr ""
51
 
52
+ #: classes/amazon-s3-and-cloudfront.php:1866
53
  msgid "Cheatin&#8217; eh?"
54
  msgstr ""
55
 
56
+ #: classes/amazon-s3-and-cloudfront.php:1870
57
  msgid "You do not have sufficient permissions to access this page."
58
  msgstr ""
59
 
60
+ #: classes/amazon-s3-and-cloudfront.php:1876
61
  msgid "No bucket name provided."
62
  msgstr ""
63
 
64
+ #: classes/amazon-s3-and-cloudfront.php:2161
65
  msgid "Error Getting Bucket Region"
66
  msgstr ""
67
 
68
+ #: classes/amazon-s3-and-cloudfront.php:2162
69
  #, php-format
70
  msgid "There was an error attempting to get the region of the bucket %s: %s"
71
  msgstr ""
72
 
73
+ #: classes/amazon-s3-and-cloudfront.php:2282
74
  msgid ""
75
  "This is a test file to check if the user has write permission to S3. Delete "
76
  "me if found."
77
  msgstr ""
78
 
79
+ #: classes/amazon-s3-and-cloudfront.php:2314
80
  #, php-format
81
  msgid ""
82
  "There was an error attempting to check the permissions of the bucket %s: %s"
83
  msgstr ""
84
 
85
+ #: classes/amazon-s3-and-cloudfront.php:2371
86
  msgid "Error creating bucket"
87
  msgstr ""
88
 
89
+ #: classes/amazon-s3-and-cloudfront.php:2372
90
  msgid "Bucket name too short."
91
  msgstr ""
92
 
93
+ #: classes/amazon-s3-and-cloudfront.php:2373
94
  msgid "Bucket name too long."
95
  msgstr ""
96
 
97
+ #: classes/amazon-s3-and-cloudfront.php:2374
98
  msgid ""
99
  "Invalid character. Bucket names can contain lowercase letters, numbers, "
100
  "periods and hyphens."
101
  msgstr ""
102
 
103
+ #: classes/amazon-s3-and-cloudfront.php:2375
104
  msgid "Error saving bucket"
105
  msgstr ""
106
 
107
+ #: classes/amazon-s3-and-cloudfront.php:2376
108
  msgid "Error fetching buckets"
109
  msgstr ""
110
 
111
+ #: classes/amazon-s3-and-cloudfront.php:2377
112
  msgid "Error getting URL preview: "
113
  msgstr ""
114
 
115
+ #: classes/amazon-s3-and-cloudfront.php:2378
116
  msgid "The changes you made will be lost if you navigate away from this page"
117
  msgstr ""
118
 
119
+ #: classes/amazon-s3-and-cloudfront.php:2436
120
  msgid "Cheatin' eh?"
121
  msgstr ""
122
 
123
+ #: classes/amazon-s3-and-cloudfront.php:2539
124
  msgctxt "Show the media library tab"
125
  msgid "Media Library"
126
  msgstr ""
127
 
128
+ #: classes/amazon-s3-and-cloudfront.php:2540
129
  msgctxt "Show the support tab"
130
  msgid "Support"
131
  msgstr ""
132
 
133
+ #: classes/amazon-s3-and-cloudfront.php:2744
134
  #, php-format
135
+ msgid ""
136
+ "<strong>WP Offload S3</strong> &mdash; The file %s has been given %s "
137
+ "permissions on Amazon S3."
138
  msgstr ""
139
 
140
+ #: classes/amazon-s3-and-cloudfront.php:2763
141
  msgid ""
142
+ "<strong>WP Offload S3 Requirement Missing</strong> &mdash; Looks like you "
143
  "don't have an image manipulation library installed on this server and "
144
  "configured with PHP. You may run into trouble if you try to edit images. "
145
  "Please setup GD or ImageMagick."
146
  msgstr ""
147
 
148
+ #: classes/amazon-s3-and-cloudfront.php:3388
149
  msgid "Quick Start Guide"
150
  msgstr ""
151
 
152
+ #: classes/amazon-s3-and-cloudfront.php:3390
153
  #, php-format
154
  msgid ""
155
  "Looks like we don't have write access to this bucket. It's likely that the "
158
  "correctly."
159
  msgstr ""
160
 
161
+ #: classes/amazon-s3-and-cloudfront.php:3392
162
  #, php-format
163
  msgid ""
164
  "Looks like we don't have access to the buckets. It's likely that the user "
166
  "Please see our %s for instructions on setting up permissions correctly."
167
  msgstr ""
168
 
169
+ #: classes/amazon-s3-and-cloudfront.php:3543
170
+ msgid "WP Offload S3 Activation"
171
+ msgstr ""
172
+
173
+ #: classes/amazon-s3-and-cloudfront.php:3544
174
+ msgid ""
175
+ "WP Offload S3 Lite and WP Offload S3 cannot both be active. We've "
176
+ "automatically deactivated WP Offload S3 Lite."
177
+ msgstr ""
178
+
179
+ #: classes/amazon-s3-and-cloudfront.php:3546
180
+ msgid "WP Offload S3 Lite Activation"
181
+ msgstr ""
182
+
183
+ #: classes/amazon-s3-and-cloudfront.php:3547
184
+ msgid ""
185
+ "WP Offload S3 Lite and WP Offload S3 cannot both be active. We've "
186
+ "automatically deactivated WP Offload S3."
187
+ msgstr ""
188
+
189
+ #: classes/amazon-s3-and-cloudfront.php:3590
190
+ msgid "More info"
191
+ msgstr ""
192
+
193
+ #: classes/amazon-s3-and-cloudfront.php:3680
194
+ msgid "this doc"
195
+ msgstr ""
196
+
197
+ #: classes/amazon-s3-and-cloudfront.php:3682
198
+ msgid "WP Offload S3 Feature Removed"
199
+ msgstr ""
200
+
201
+ #: classes/amazon-s3-and-cloudfront.php:3683
202
+ #, php-format
203
+ msgid ""
204
+ "The \"Copy HiDPI (@2x) Images\" feature has been removed as of version 1.1 "
205
+ "of WP Offload S3. It looks like you had this feature turned on. Please see "
206
+ "%s for why we removed this feature and how you can continue copying @2x "
207
+ "images to S3."
208
+ msgstr ""
209
+
210
+ #: classes/as3cf-notices.php:433
211
  msgid "Error dismissing notice."
212
  msgstr ""
213
 
214
+ #: classes/as3cf-notices.php:448
215
  msgid "Invalid notice ID."
216
  msgstr ""
217
 
218
+ #: classes/as3cf-plugin-compatibility.php:202
219
  msgid "WP Offload S3 Compatibility Addons"
220
  msgstr ""
221
 
222
+ #: classes/as3cf-plugin-compatibility.php:204
223
  msgid "compatibility addons"
224
  msgstr ""
225
 
226
+ #: classes/as3cf-plugin-compatibility.php:205
227
  #, php-format
228
  msgid ""
229
  "To get WP Offload S3 to work with certain 3rd party plugins, you might need "
232
  "about each addon to determine if you need it or not."
233
  msgstr ""
234
 
235
+ #: classes/as3cf-plugin-compatibility.php:211
236
  #, php-format
237
  msgid ""
238
  "You will need to purchase a license to get access to these addons. If you're "
240
  "to %s."
241
  msgstr ""
242
 
243
+ #: classes/as3cf-plugin-compatibility.php:212
244
  msgid "View Licenses"
245
  msgstr ""
246
 
247
+ #: classes/as3cf-plugin-compatibility.php:667
248
+ #, php-format
249
+ msgid "The local directory %s does not exist and could not be created."
250
+ msgstr ""
251
+
252
+ #: classes/as3cf-plugin-compatibility.php:668
253
+ #: classes/as3cf-plugin-compatibility.php:682
254
  #: classes/upgrades/as3cf-meta-wp-error.php:72
255
  #, php-format
256
  msgid "There was an error attempting to download the file %s from S3: %s"
257
  msgstr ""
258
 
259
+ #: classes/as3cf-upgrade.php:283
260
  #, php-format
261
  msgid ""
262
  "<strong>Running %s Update</strong> &mdash; We&#8217;re going through all the "
266
  "performance."
267
  msgstr ""
268
 
269
+ #: classes/as3cf-upgrade.php:284
270
  msgid "Pause Update"
271
  msgstr ""
272
 
273
+ #: classes/as3cf-upgrade.php:288
274
  #, php-format
275
  msgid ""
276
  "<strong>%s Update Paused</strong> &mdash; Updating Media Library %s has been "
277
  "paused."
278
  msgstr ""
279
 
280
+ #: classes/as3cf-upgrade.php:289
281
  msgid "Restart Update"
282
  msgstr ""
283
 
284
+ #: classes/as3cf-upgrade.php:292
285
  #, php-format
286
  msgid ""
287
  "<strong>Error Updating %s</strong> &mdash; We ran into some errors "
289
  "uploaded to S3. Please check your error log for details. (#%d)"
290
  msgstr ""
291
 
292
+ #: classes/as3cf-upgrade.php:293
293
  msgid "Try Run It Again"
294
  msgstr ""
295
 
296
+ #: classes/as3cf-upgrade.php:408
297
  #, php-format
298
  msgid "Every %d Minutes"
299
  msgstr ""
317
  "style=\"white-space:nowrap;\">(e.g. s3-us-west-2.amazonaws.com)</span>."
318
  msgstr ""
319
 
320
+ #: classes/wp-aws-compatibility-check.php:323
321
  msgid "deactivate"
322
  msgstr ""
323
 
324
+ #: classes/wp-aws-compatibility-check.php:324
325
  #, php-format
326
  msgid "You can %s the %s plugin to get rid of this notice."
327
  msgstr ""
328
 
329
+ #: classes/wp-aws-compatibility-check.php:327
330
  #, php-format
331
  msgid "%s has been disabled as it requires the %s plugin."
332
  msgstr ""
333
 
334
+ #: classes/wp-aws-compatibility-check.php:331
335
  msgid "which is currently disabled."
336
  msgstr ""
337
 
338
+ #: classes/wp-aws-compatibility-check.php:333
339
  msgid "It appears to be installed already."
340
  msgstr ""
341
 
342
+ #: classes/wp-aws-compatibility-check.php:335
343
  msgctxt "Activate plugin"
344
  msgid "Activate it now."
345
  msgstr ""
346
 
347
+ #: classes/wp-aws-compatibility-check.php:342
348
  #, php-format
349
  msgid "<a href=\"%s\">Install</a> and activate it."
350
  msgstr ""
351
 
352
+ #: classes/wp-aws-compatibility-check.php:353
353
  #, php-format
354
  msgid ""
355
  "%s has been disabled as it requires version %s or later of the %s plugin."
356
  msgstr ""
357
 
358
+ #: classes/wp-aws-compatibility-check.php:356
359
  #, php-format
360
  msgid "You currently have version %s installed."
361
  msgstr ""
362
 
363
+ #: classes/wp-aws-compatibility-check.php:363
364
+ #: classes/wp-aws-compatibility-check.php:401
365
  #, php-format
366
  msgid "A valid license for %s is required to update."
367
  msgstr ""
368
 
369
+ #: classes/wp-aws-compatibility-check.php:371
370
  msgid "Update to the latest version"
371
  msgstr ""
372
 
373
+ #: classes/wp-aws-compatibility-check.php:383
374
  #, php-format
375
  msgid ""
376
  "%1$s has been disabled because it is not a supported addon of the %2$s "
377
  "plugin."
378
  msgstr ""
379
 
380
+ #: classes/wp-aws-compatibility-check.php:392
381
  #, php-format
382
  msgid ""
383
  "%1$s has been disabled because it will not work with the version of the %2$s "
384
  "plugin installed. %1$s %3$s or later is required."
385
  msgstr ""
386
 
387
+ #: classes/wp-aws-compatibility-check.php:395
388
  #, php-format
389
  msgid "Update %s to the latest version"
390
  msgstr ""
391
 
392
+ #: classes/wp-aws-compatibility-check.php:464
393
  #, php-format
394
  msgid "The %s plugin has been deactivated."
395
  msgstr ""
486
  msgid "Change"
487
  msgstr ""
488
 
489
+ #: view/cloudfront-setting.php:4
490
+ #: view/deprecated-domain-setting.php:49
491
+ msgid "Invalid character. Letters, numbers, periods and hyphens are allowed."
492
  msgstr ""
493
 
494
  #: view/debug-info.php:2
500
  msgid "Download"
501
  msgstr ""
502
 
503
+ #: view/deprecated-domain-setting.php:5
504
  msgid "Domain:"
505
  msgstr ""
506
 
507
+ #: view/deprecated-domain-setting.php:30
508
  msgid "Bucket name as subdomain"
509
  msgstr ""
510
 
511
+ #: view/deprecated-domain-setting.php:35
512
  msgid "Bucket name in path"
513
  msgstr ""
514
 
515
+ #: view/deprecated-domain-setting.php:40
516
  msgid "Bucket name as domain"
517
  msgstr ""
518
 
519
+ #: view/deprecated-domain-setting.php:45
520
  msgid "CloudFront or custom domain"
521
  msgstr ""
522
 
523
+ #: view/domain-setting.php:19
524
+ msgid "CloudFront or Custom Domain"
525
+ msgstr ""
526
+
527
+ #: view/domain-setting.php:21
528
+ msgid ""
529
+ "Replace the default S3 domain and path with your CloudFront domain or any "
530
+ "domain."
531
  msgstr ""
532
 
533
  #: view/error-access.php:4
534
  msgid "Access Denied to Bucket"
535
  msgstr ""
536
 
537
+ #: view/notice.php:18
538
+ msgid "Hide"
539
+ msgstr ""
540
+
541
+ #: view/notice.php:18
542
+ msgid "Show"
543
+ msgstr ""
544
+
545
  #: view/settings.php:10
546
  msgid "Settings saved."
547
  msgstr ""
548
 
549
+ #: view/settings.php:48
550
  msgid "Enable/Disable the Plugin"
551
  msgstr ""
552
 
553
+ #: view/settings.php:56
554
  msgid "Copy Files to S3"
555
  msgstr ""
556
 
557
+ #: view/settings.php:58
558
  msgid ""
559
  "When a file is uploaded to the Media Library, copy it to S3. Existing files "
560
  "are <em>not</em> copied to S3."
561
  msgstr ""
562
 
563
+ #: view/settings.php:71
564
  msgid "Rewrite File URLs"
565
  msgstr ""
566
 
567
+ #: view/settings.php:73
568
  msgid ""
569
  "For Media Library files that have been copied to S3, rewrite the URLs so "
570
  "that they are served from S3/CloudFront instead of your server."
571
  msgstr ""
572
 
573
+ #: view/settings.php:80
574
  msgid "Configure File URLs"
575
  msgstr ""
576
 
577
+ #: view/settings.php:101
578
  msgid "Path"
579
  msgstr ""
580
 
581
+ #: view/settings.php:103
582
+ msgid "By default the path is the same as your local WordPress files."
583
  msgstr ""
584
 
585
+ #: view/settings.php:127
586
  msgid "Year/Month"
587
  msgstr ""
588
 
589
+ #: view/settings.php:129
590
  msgid "Add the Year/Month in the URL."
591
  msgstr ""
592
 
593
+ #: view/settings.php:138
594
+ msgid "SSL"
595
  msgstr ""
596
 
597
+ #: view/settings.php:142
598
+ msgid "Controls the protocol of the S3 URLs."
599
+ msgstr ""
600
+
601
+ #: view/settings.php:152
602
  msgid "Same as request"
603
  msgstr ""
604
 
605
+ #: view/settings.php:153
606
  msgid "When the request is https://, use https:// for the file URL as well."
607
  msgstr ""
608
 
609
+ #: view/settings.php:157
610
  msgid "Always SSL"
611
  msgstr ""
612
 
613
+ #: view/settings.php:158
614
  msgid "Forces https:// to be used."
615
  msgstr ""
616
 
617
+ #: view/settings.php:160
618
  msgid ""
619
  "You cannot use the \"Bucket as a subdomain\" domain option when using SSL."
620
  msgstr ""
621
 
622
+ #: view/settings.php:165
623
  msgid "Always non-SSL"
624
  msgstr ""
625
 
626
+ #: view/settings.php:166
627
  msgid "Forces http:// to be used."
628
  msgstr ""
629
 
630
+ #: view/settings.php:172
631
  msgid "Advanced Options"
632
  msgstr ""
633
 
634
+ #: view/settings.php:181
635
  msgid "Remove Files From Server"
636
  msgstr ""
637
 
638
+ #: view/settings.php:182
639
  msgid "Once a file has been copied to S3, remove it from the local server."
640
  msgstr ""
641
 
642
+ #: view/settings.php:186
643
  msgid ""
644
  "<strong>Broken URLs</strong> &mdash; There will be broken URLs for files "
645
  "that don't exist locally. You can fix this by enabling <strong>Rewrite File "
646
  "URLs</strong> to use the S3 URLs."
647
  msgstr ""
648
 
649
+ #: view/settings.php:197
 
 
 
 
 
 
650
  #, php-format
651
  msgid ""
652
  "<strong>Warning</strong> &mdash; Some plugins depend on the file being "
653
  "present on the local server and may not work when the file is removed. %s"
654
  msgstr ""
655
 
656
+ #: view/settings.php:215
657
  msgid "Object Versioning"
658
  msgstr ""
659
 
660
+ #: view/settings.php:217
661
  msgid ""
662
  "Append a timestamp to the S3 file path. Recommended when using CloudFront so "
663
  "you don't have to worry about cache invalidation."
664
  msgstr ""
665
 
666
+ #: view/settings.php:224
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
667
  msgid "Save Changes"
668
  msgstr ""
669
 
languages/amazon-s3-and-cloudfront-pt-br.mo DELETED
Binary file
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
- === WP Offload S3 ===
2
  Contributors: bradt, deliciousbrains
3
  Tags: uploads, amazon, s3, amazon s3, mirror, admin, media, cdn, cloudfront
4
  Requires at least: 3.7
5
  Tested up to: 4.4
6
- Stable tag: 0.9.11
7
  License: GPLv3
8
 
9
  Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery.
@@ -69,6 +69,25 @@ This version requires PHP 5.3.3+ and the Amazon Web Services plugin
69
 
70
  == Changelog ==
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  = WP Offload S3 0.9.11 - 2015-12-19 =
73
  * Bug fix: Responsive images in post content not working when served from S3
74
  * Bug fix: Responsive images using wrong image size when there are multiple images with the same width
1
+ === WP Offload S3 Lite ===
2
  Contributors: bradt, deliciousbrains
3
  Tags: uploads, amazon, s3, amazon s3, mirror, admin, media, cdn, cloudfront
4
  Requires at least: 3.7
5
  Tested up to: 4.4
6
+ Stable tag: 1.0
7
  License: GPLv3
8
 
9
  Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery.
69
 
70
  == Changelog ==
71
 
72
+ = WP Offload S3 Lite 1.0 - 2016-03-07 =
73
+ * New: Plugin renamed to "WP Offload S3 Lite"
74
+ * New: Define any and all settings with a constant in wp-config.php
75
+ * New: Documentation links for each setting
76
+ * Improvement: Simplified domain setting UI
77
+ * Improvement: Far future expiration header set by default
78
+ * Improvement: Newly created bucket now immediately appears in the bucket list
79
+ * Improvement: Cleanup user meta on uninstall
80
+ * Improvement: WP Retina 2x integration [removed](https://deliciousbrains.com/wp-offload-s3/doc/copy-hidpi-2x-images-support/)
81
+ * 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
82
+ * Bug fix: Responsive srcset PHP notices
83
+ * Bug fix: Compatibility addon notices displayed to non-admin users
84
+ * Bug fix: Potential PHP fatal error in MySQL version check in diagnostic log
85
+ * Bug fix: Missing image library notices displaying before plugin is setup
86
+
87
+ = WP Offload S3 0.9.12 - 2016-02-03 =
88
+ * Improvement: Compatibility with WP Offload S3 Assets 1.1
89
+ * Bug fix: Object versioned responsive images in post content not working when served from S3 on WordPress 4.4+
90
+
91
  = WP Offload S3 0.9.11 - 2015-12-19 =
92
  * Bug fix: Responsive images in post content not working when served from S3
93
  * Bug fix: Responsive images using wrong image size when there are multiple images with the same width
uninstall.php CHANGED
@@ -20,7 +20,8 @@ $options = array(
20
  'tantan_wordpress_s3',
21
  'update_meta_with_region_session',
22
  'update_file_sizes_session',
23
- 'as3cf_compat_addons_to_install'
 
24
  );
25
 
26
  $postmeta = array(
@@ -41,4 +42,9 @@ $transients = array(
41
  'subsite' => array( 'wpos3_site_space_used' ),
42
  );
43
 
44
- $as3cf_uninstall = new WP_AWS_Uninstall( $options, $postmeta, $crons, $transients );
 
 
 
 
 
20
  'tantan_wordpress_s3',
21
  'update_meta_with_region_session',
22
  'update_file_sizes_session',
23
+ 'update_meta_error_session',
24
+ 'as3cf_compat_addons_to_install',
25
  );
26
 
27
  $postmeta = array(
42
  'subsite' => array( 'wpos3_site_space_used' ),
43
  );
44
 
45
+ $usermeta = array(
46
+ 'as3cf_notices',
47
+ 'as3cf_dismissed_notices',
48
+ );
49
+
50
+ $as3cf_uninstall = new WP_AWS_Uninstall( $options, $postmeta, $crons, $transients, $usermeta );
view/bucket-setting.php CHANGED
@@ -12,10 +12,10 @@ $tr_class = ( isset( $tr_class ) ) ? $tr_class : '';
12
  <a id="<?php echo $prefix; ?>-view-bucket" target="_blank" class="as3cf-view-bucket" href="<?php echo $this->get_aws_bucket_link( $selected_bucket, $selected_bucket_prefix ); ?>" title="<?php _e( 'View in S3 console', 'amazon-s3-and-cloudfront' ); ?>">
13
  <span class="dashicons dashicons-external"></span>
14
  </a>
15
- <?php if ( ! defined( $constant ) ) { ?>
16
  <a href="#" class="as3cf-change-bucket" data-as3cf-modal=".as3cf-bucket-container"><?php _e( 'Change', 'amazon-s3-and-cloudfront' ); ?></a>
17
  <?php } else {
18
- _e( '(defined in wp-config.php)', 'amazon-s3-and-cloudfront' );
19
  } ?>
20
  <input id="<?php echo $prefix; ?>-bucket" type="hidden" class="no-compare" name="bucket" value="<?php echo esc_attr( $selected_bucket ); ?>">
21
  <?php
12
  <a id="<?php echo $prefix; ?>-view-bucket" target="_blank" class="as3cf-view-bucket" href="<?php echo $this->get_aws_bucket_link( $selected_bucket, $selected_bucket_prefix ); ?>" title="<?php _e( 'View in S3 console', 'amazon-s3-and-cloudfront' ); ?>">
13
  <span class="dashicons dashicons-external"></span>
14
  </a>
15
+ <?php if ( ! defined( $constant ) && ! $this->get_defined_setting( 'bucket', false ) ) { ?>
16
  <a href="#" class="as3cf-change-bucket" data-as3cf-modal=".as3cf-bucket-container"><?php _e( 'Change', 'amazon-s3-and-cloudfront' ); ?></a>
17
  <?php } else {
18
+ echo '<span class="as3cf-defined-in-config">' . __( 'defined in wp-config.php', 'amazon-s3-and-cloudfront' ) . '</span>';
19
  } ?>
20
  <input id="<?php echo $prefix; ?>-bucket" type="hidden" class="no-compare" name="bucket" value="<?php echo esc_attr( $selected_bucket ); ?>">
21
  <?php
view/checkbox.php CHANGED
@@ -2,10 +2,11 @@
2
  $value = ( isset( $value ) ) ? $value : $this->get_setting( $key );
3
  $class = ( isset( $class ) ) ? 'class="' . $class . '"' : '';
4
  $disabled = ( isset( $disabled ) && $disabled ) ? ' disabled' : '';
 
5
  ?>
6
- <div id="<?php echo $key; ?>-wrap" data-checkbox="<?php echo $key; ?>" class="as3cf-switch<?php echo $disabled . $value ? ' on' : ''; ?>">
7
- <span class="on <?php echo $value ? 'checked' : ''; ?>">ON</span>
8
- <span class="off <?php echo ! $value ? 'checked' : ''; ?>">OFF</span>
9
- <input type="hidden" name="<?php echo $key; ?>" value="0" />
10
- <input type="checkbox" name="<?php echo $key; ?>" value="1" id="<?php echo $key; ?>" <?php echo $value ? 'checked="checked" ' : ''; ?> <?php echo $class ?>/>
11
  </div>
2
  $value = ( isset( $value ) ) ? $value : $this->get_setting( $key );
3
  $class = ( isset( $class ) ) ? 'class="' . $class . '"' : '';
4
  $disabled = ( isset( $disabled ) && $disabled ) ? ' disabled' : '';
5
+ $values = ( isset( $values ) && is_array( $values ) && 2 === count( $values ) ) ? $values : array( 0, 1 );
6
  ?>
7
+ <div id="<?php echo $key; ?>-wrap" data-checkbox="<?php echo $key; ?>" class="as3cf-switch<?php echo $disabled . ( $value == $values[1] ? ' on' : '' ); ?>">
8
+ <span class="on <?php echo $value == $values[1] ? 'checked' : ''; ?>">ON</span>
9
+ <span class="off <?php echo $value == $values[0] ? 'checked' : ''; ?>">OFF</span>
10
+ <input type="hidden" name="<?php echo $key; ?>" value="<?php echo $values[0]; ?>" />
11
+ <input type="checkbox" name="<?php echo $key; ?>" value="<?php echo $values[1]; ?>" id="<?php echo $key; ?>" <?php echo $value == $values[1] ? 'checked="checked" ' : ''; ?> <?php echo $class ?>/>
12
  </div>
view/cloudfront-setting.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <p class="as3cf-setting domain cloudfront <?php echo ( 'cloudfront' == $domain ) ? '' : 'hide'; // xss ok ?>">
2
+ <input type="text" name="cloudfront" value="<?php echo esc_attr( $this->get_setting( 'cloudfront' ) ); ?>" size="30" <?php echo $disabled_attr; ?> />
3
+ <span class="as3cf-validation-error" style="display: none;">
4
+ <?php _e( 'Invalid character. Letters, numbers, periods and hyphens are allowed.', 'amazon-s3-and-cloudfront' ); ?>
5
+ </span>
6
+ </p>
view/deprecated-domain-setting.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $tr_class = ( isset( $tr_class ) ) ? $tr_class : ''; ?>
3
+ <tr class="<?php echo $tr_class; ?>">
4
+ <td>
5
+ <h4><?php _e( 'Domain:', 'amazon-s3-and-cloudfront' ) ?></h4>
6
+ </td>
7
+ <td>
8
+ <?php
9
+ $domain = $this->get_setting( 'domain' );
10
+ $subdomain_disabled = '';
11
+ $subdomain_class = '';
12
+ if ( 'https' == $this->get_setting( 'ssl' ) ) {
13
+ if ( 'subdomain' == $domain ) {
14
+ $domain = 'path';
15
+ }
16
+ $subdomain_disabled = 'disabled="disabled"';
17
+ $subdomain_class = 'disabled';
18
+ }
19
+
20
+ if ( true === $disabled ) {
21
+ $subdomain_disabled = 'disabled="disabled"';
22
+ $subdomain_class = 'disabled';
23
+ }
24
+
25
+ echo $setting_msg;
26
+ ?>
27
+ <div class="as3cf-domain as3cf-radio-group">
28
+ <label class="subdomain-wrap <?php echo $subdomain_class; // xss ok?>">
29
+ <input type="radio" name="domain" value="subdomain" <?php checked( $domain, 'subdomain' ); ?> <?php echo $subdomain_disabled; // xss ok ?>>
30
+ <?php _e( 'Bucket name as subdomain', 'amazon-s3-and-cloudfront' ); ?>
31
+ <p>http://bucket-name.s3.amazon.com/&hellip;</p>
32
+ </label>
33
+ <label>
34
+ <input type="radio" name="domain" value="path" <?php checked( $domain, 'path' ); ?> <?php echo $disabled_attr; ?>>
35
+ <?php _e( 'Bucket name in path', 'amazon-s3-and-cloudfront' ); ?>
36
+ <p>http://s3.amazon.com/bucket-name/&hellip;</p>
37
+ </label>
38
+ <label>
39
+ <input type="radio" name="domain" value="virtual-host" <?php checked( $domain, 'virtual-host' ); ?> <?php echo $disabled_attr; ?>>
40
+ <?php _e( 'Bucket name as domain', 'amazon-s3-and-cloudfront' ); ?>
41
+ <p>http://bucket-name/&hellip;</p>
42
+ </label>
43
+ <label>
44
+ <input id="cloudfront" type="radio" name="domain" value="cloudfront" <?php checked( $domain, 'cloudfront' ); ?> <?php echo $disabled_attr; ?>>
45
+ <?php _e( 'CloudFront or custom domain', 'amazon-s3-and-cloudfront' ); ?>
46
+ <p class="as3cf-setting cloudfront <?php echo ( 'cloudfront' == $domain ) ? '' : 'hide'; // xss ok ?>">
47
+ <input type="text" name="cloudfront" value="<?php echo esc_attr( $this->get_setting( 'cloudfront' ) ); ?>" size="30" <?php echo $disabled_attr; ?> />
48
+ <span class="as3cf-validation-error" style="display: none;">
49
+ <?php _e( 'Invalid character. Letters, numbers, periods and hyphens are allowed.', 'amazon-s3-and-cloudfront' ); ?>
50
+ </span>
51
+ </p>
52
+ </label>
53
+ </div>
54
+ </td>
55
+ </tr>
view/domain-setting.php CHANGED
@@ -1,48 +1,30 @@
1
  <?php
2
- $tr_class = ( isset( $tr_class ) ) ? $tr_class : ''; ?>
3
- <tr class="<?php echo $tr_class; ?>">
 
 
 
 
 
 
4
  <td>
5
- <h4><?php _e( 'Domain:', 'amazon-s3-and-cloudfront' ) ?></h4>
 
 
 
 
6
  </td>
7
  <td>
 
 
 
 
 
 
8
  <?php
9
- $domain = $this->get_setting( 'domain' );
10
- $subdomain_disabled = '';
11
- $subdomain_class = '';
12
- if ( 'https' == $this->get_setting( 'ssl' ) ) {
13
- if ( 'subdomain' == $domain ) {
14
- $domain = 'path';
15
- }
16
- $subdomain_disabled = 'disabled="disabled"';
17
- $subdomain_class = 'disabled';
18
- }
19
  ?>
20
- <div class="as3cf-domain as3cf-radio-group">
21
- <label class="subdomain-wrap <?php echo $subdomain_class; // xss ok?>">
22
- <input type="radio" name="domain" value="subdomain" <?php checked( $domain, 'subdomain' ); ?> <?php echo $subdomain_disabled; // xss ok ?>>
23
- <?php _e( 'Bucket name as subdomain', 'amazon-s3-and-cloudfront' ); ?>
24
- <p>http://bucket-name.s3.amazon.com/&hellip;</p>
25
- </label>
26
- <label>
27
- <input type="radio" name="domain" value="path" <?php checked( $domain, 'path' ); ?>>
28
- <?php _e( 'Bucket name in path', 'amazon-s3-and-cloudfront' ); ?>
29
- <p>http://s3.amazon.com/bucket-name/&hellip;</p>
30
- </label>
31
- <label>
32
- <input type="radio" name="domain" value="virtual-host" <?php checked( $domain, 'virtual-host' ); ?>>
33
- <?php _e( 'Bucket name as domain', 'amazon-s3-and-cloudfront' ); ?>
34
- <p>http://bucket-name/&hellip;</p>
35
- </label>
36
- <label>
37
- <input id="cloudfront" type="radio" name="domain" value="cloudfront" <?php checked( $domain, 'cloudfront' ); ?>>
38
- <?php _e( 'CloudFront or custom domain', 'amazon-s3-and-cloudfront' ); ?>
39
- <p class="as3cf-setting cloudfront <?php echo ( 'cloudfront' == $domain ) ? '' : 'hide'; // xss ok ?>">
40
- <input type="text" name="cloudfront" value="<?php echo esc_attr( $this->get_setting( 'cloudfront' ) ); ?>" size="30" />
41
- <span class="as3cf-validation-error" style="display: none;">
42
- <?php _e( 'Invalid character. Letters, numbers, periods and hyphens are allowed.', 'amazon-s3-and-cloudfront' ); ?>
43
- </span>
44
- </p>
45
- </label>
46
- </div>
47
  </td>
48
  </tr>
1
  <?php
2
+ $domain = $this->get_setting( 'domain' );
3
+ $args = $this->get_setting_args( 'domain' );
4
+ $args['tr_class'] = $args['tr_class'] . ' configure-url url-preview';
5
+ if ( $this->show_deprecated_domain_setting( $domain ) ) {
6
+ return $this->render_view( 'deprecated-domain-setting', $args );
7
+ }
8
+ ?>
9
+ <tr class="<?php echo $args['tr_class']; ?>">
10
  <td>
11
+ <?php
12
+ $args['values'] = array( 'path', 'cloudfront' );
13
+ $args['class'] = 'sub-toggle';
14
+ $this->render_view( 'checkbox', $args );
15
+ ?>
16
  </td>
17
  <td>
18
+ <?php echo $args['setting_msg']; ?>
19
+ <h4><?php _e( 'CloudFront or Custom Domain', 'amazon-s3-and-cloudfront' ) ?></h4>
20
+ <p class="domain-desc">
21
+ <?php _e( 'Replace the default S3 domain and path with your CloudFront domain or any domain.', 'amazon-s3-and-cloudfront' ); ?>
22
+ <?php echo $this->settings_more_info_link( 'domain' ); ?>
23
+ </p>
24
  <?php
25
+ $args = $this->get_setting_args( 'cloudfront' );
26
+ $args['domain'] = $domain;
27
+ $this->render_view( 'cloudfront-setting', $args );
 
 
 
 
 
 
 
28
  ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  </td>
30
  </tr>
view/failure-notice.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <ol class="as3cf-notice-toggle-list">
2
+ <?php foreach ( $errors as $file => $value ) : ?>
3
+ <li><?php echo $file; ?></li>
4
+ <?php endforeach; ?>
5
+ </ol>
view/notice.php CHANGED
@@ -1,18 +1,28 @@
1
  <?php
2
- $type = ( isset( $type ) ) ? $type : 'notice-info';
3
- $dismissible = ( isset( $dismissible ) ) ? $dismissible : false;
4
- $inline = ( isset( $inline ) ) ? $inline : false;
5
- $id = ( isset( $id ) ) ? 'id="' . $id . '"' : '';
6
- $style = ( isset( $style ) ) ? $style : '';
7
- $auto_p = ( isset( $auto_p ) ) ? $auto_p : 'true';
8
- $class = ( isset( $class ) ) ? $class : '';
 
 
9
  ?>
10
  <div <?php echo $id; ?> class="notice <?php echo $type; ?><?php echo ( $dismissible ) ? ' is-dismissible' : ''; ?> as3cf-notice <?php echo ( $inline ) ? ' inline' : ''; ?> <?php echo ( '' !== $class ) ? ' ' . $class : ''; ?>" style="<?php echo $style; ?>">
11
  <?php if ( $auto_p ) : ?>
12
  <p>
13
  <?php endif; ?>
14
  <?php echo $message; // xss ok ?>
 
 
 
15
  <?php if ( $auto_p ) : ?>
16
  </p>
17
  <?php endif; ?>
 
 
 
 
 
18
  </div>
1
  <?php
2
+ $type = ( isset( $type ) ) ? $type : 'notice-info';
3
+ $dismissible = ( isset( $dismissible ) ) ? $dismissible : false;
4
+ $inline = ( isset( $inline ) ) ? $inline : false;
5
+ $id = ( isset( $id ) ) ? 'id="' . $id . '"' : '';
6
+ $style = ( isset( $style ) ) ? $style : '';
7
+ $auto_p = ( isset( $auto_p ) ) ? $auto_p : 'true';
8
+ $class = ( isset( $class ) ) ? $class : '';
9
+ $show_callback = ( isset( $show_callback ) && false !== $show_callback ) ? array( $GLOBALS[ $show_callback[0] ], $show_callback[1] ) : false;
10
+ $callback_args = ( isset( $callback_args ) ) ? $callback_args : array();
11
  ?>
12
  <div <?php echo $id; ?> class="notice <?php echo $type; ?><?php echo ( $dismissible ) ? ' is-dismissible' : ''; ?> as3cf-notice <?php echo ( $inline ) ? ' inline' : ''; ?> <?php echo ( '' !== $class ) ? ' ' . $class : ''; ?>" style="<?php echo $style; ?>">
13
  <?php if ( $auto_p ) : ?>
14
  <p>
15
  <?php endif; ?>
16
  <?php echo $message; // xss ok ?>
17
+ <?php if ( false !== $show_callback && is_callable( $show_callback ) ) : ?>
18
+ <a href="#" class="as3cf-notice-toggle" data-hide="<?php _e( 'Hide', 'amazon-s3-and-cloudfront' ); ?>"><?php _e( 'Show', 'amazon-s3-and-cloudfront' ); ?></a>
19
+ <?php endif; ?>
20
  <?php if ( $auto_p ) : ?>
21
  </p>
22
  <?php endif; ?>
23
+ <?php if ( false !== $show_callback && is_callable( $show_callback ) ) : ?>
24
+ <div class="as3cf-notice-toggle-content" style="display: none;">
25
+ <?php call_user_func_array( $show_callback, $callback_args ); ?>
26
+ </div>
27
+ <?php endif; ?>
28
  </div>
view/settings.php CHANGED
@@ -22,7 +22,7 @@ $selected_bucket_prefix = $this->get_object_prefix(); ?>
22
  </div>
23
 
24
  <?php
25
- do_action( 'as3cf_media_pre_tab_render' );
26
  $this->render_bucket_permission_errors(); ?>
27
 
28
  <div class="as3cf-main-settings">
@@ -39,28 +39,41 @@ $selected_bucket_prefix = $this->get_object_prefix(); ?>
39
  'prefix' => $prefix,
40
  'selected_bucket' => $selected_bucket,
41
  'selected_bucket_prefix' => $selected_bucket_prefix,
42
- 'tr_class' => 'as3cf-border-bottom',
43
  )
44
  ); ?>
 
 
45
  <tr class="as3cf-setting-title">
46
  <td colspan="2"><h3><?php _e( 'Enable/Disable the Plugin', 'amazon-s3-and-cloudfront' ); ?></h3></td>
47
  </tr>
48
- <tr>
49
  <td>
50
- <?php $this->render_view( 'checkbox', array( 'key' => 'copy-to-s3' ) ); ?>
51
  </td>
52
  <td>
 
53
  <h4><?php _e( 'Copy Files to S3', 'amazon-s3-and-cloudfront' ) ?></h4>
54
- <p><?php _e( 'When a file is uploaded to the Media Library, copy it to S3. Existing files are <em>not</em> copied to S3.', 'amazon-s3-and-cloudfront' ) ?></p>
 
 
 
 
55
  </td>
56
  </tr>
57
- <tr class="as3cf-border-bottom">
 
58
  <td>
59
- <?php $this->render_view( 'checkbox', array( 'key' => 'serve-from-s3' ) ); ?>
60
  </td>
61
  <td>
 
62
  <h4><?php _e( 'Rewrite File URLs', 'amazon-s3-and-cloudfront' ) ?></h4>
63
- <p><?php _e( 'For Media Library files that have been copied to S3, rewrite the URLs so that they are served from S3/CloudFront instead of your server.', 'amazon-s3-and-cloudfront' ) ?></p>
 
 
 
 
64
  </td>
65
  </tr>
66
  <tr class="configure-url as3cf-setting-title">
@@ -76,54 +89,79 @@ $selected_bucket_prefix = $this->get_object_prefix(); ?>
76
  </div>
77
  </td>
78
  </tr>
79
- <?php $this->render_view( 'domain-setting', array( 'tr_class' => 'configure-url url-preview' ) ); ?>
80
- <tr class="configure-url url-preview">
 
81
  <td>
82
- <?php $this->render_view( 'checkbox', array( 'key' => 'enable-object-prefix', 'class' => 'sub-toggle' ) ); ?>
 
83
  </td>
84
  <td>
 
85
  <h4><?php _e( 'Path', 'amazon-s3-and-cloudfront' ) ?></h4>
86
  <p class="object-prefix-desc">
87
- <?php _e( 'By default the path is the same as your local WordPress files:', 'amazon-s3-and-cloudfront' ); ?>
88
- <em><?php echo $this->get_default_object_prefix(); // xss ok ?></em>
89
  </p>
90
  <p class="as3cf-setting enable-object-prefix <?php echo ( $this->get_setting( 'enable-object-prefix' ) ) ? '' : 'hide'; // xss ok ?>">
91
- <input type="text" name="object-prefix" value="<?php echo esc_attr( $this->get_setting( 'object-prefix' ) ); ?>" size="30" />
 
 
 
 
 
 
 
 
92
  </p>
93
  </td>
94
  </tr>
95
- <tr class="configure-url url-preview">
 
 
96
  <td>
97
- <?php $this->render_view( 'checkbox', array( 'key' => 'use-yearmonth-folders' ) ); ?>
98
  </td>
99
  <td>
 
100
  <h4><?php _e( 'Year/Month', 'amazon-s3-and-cloudfront' ) ?></h4>
101
  <p>
102
  <?php _e( 'Add the Year/Month in the URL.' ); ?>
 
103
  </p>
104
  </td>
105
  </tr>
106
- <tr class="configure-url as3cf-border-bottom url-preview">
 
 
107
  <td>
108
- <h4><?php _e( 'SSL:', 'amazon-s3-and-cloudfront' ) ?></h4>
109
  </td>
110
  <td>
 
 
 
 
111
  <?php
112
- $ssl = $this->get_setting( 'ssl' ); ?>
 
 
113
  <div class="as3cf-ssl as3cf-radio-group">
114
  <label>
115
- <input type="radio" name="ssl" value="request" <?php checked( $ssl, 'request' ); ?>>
116
  <?php _e( 'Same as request', 'amazon-s3-and-cloudfront' ); ?>
117
  <p><?php _e( 'When the request is https://, use https:// for the file URL as well.', 'amazon-s3-and-cloudfront' ); ?></p>
118
  </label>
119
  <label>
120
- <input type="radio" name="ssl" value="https" <?php checked( $ssl, 'https' ); ?>>
121
  <?php _e( 'Always SSL', 'amazon-s3-and-cloudfront' ); ?>
122
  <p><?php _e( 'Forces https:// to be used.', 'amazon-s3-and-cloudfront' ); ?></p>
123
- <p><?php _e( 'You cannot use the "Bucket as a subdomain" domain option when using SSL.', 'amazon-s3-and-cloudfront' ); ?></p>
124
- </label>
 
 
125
  <label>
126
- <input type="radio" name="ssl" value="http" <?php checked( $ssl, 'http' ); ?>>
127
  <?php _e( 'Always non-SSL', 'amazon-s3-and-cloudfront' ); ?>
128
  <p><?php _e( 'Forces http:// to be used.', 'amazon-s3-and-cloudfront' ); ?></p>
129
  </label>
@@ -133,13 +171,17 @@ $selected_bucket_prefix = $this->get_object_prefix(); ?>
133
  <tr class="advanced-options as3cf-setting-title">
134
  <td colspan="2"><h3><?php _e( 'Advanced Options', 'amazon-s3-and-cloudfront' ); ?></h3></td>
135
  </tr>
136
- <tr class="advanced-options">
 
137
  <td>
138
- <?php $this->render_view( 'checkbox', array( 'key' => 'remove-local-file' ) ); ?>
139
  </td>
140
  <td>
 
141
  <h4><?php _e( 'Remove Files From Server', 'amazon-s3-and-cloudfront' ) ?></h4>
142
- <p><?php _e( 'Once a file has been copied to S3, remove it from the local server.', 'amazon-s3-and-cloudfront' ) ?></p>
 
 
143
  <?php
144
  $lost_files_msg = apply_filters( 'as3cf_lost_files_notice', __( '<strong>Broken URLs</strong> &mdash; There will be broken URLs for files that don\'t exist locally. You can fix this by enabling <strong>Rewrite File URLs</strong> to use the S3 URLs.', 'amazon-s3-and-cloudfront' ) );
145
  $lost_files_args = array(
@@ -151,7 +193,7 @@ $selected_bucket_prefix = $this->get_object_prefix(); ?>
151
  );
152
  $this->render_view( 'notice', $lost_files_args );
153
 
154
- $remove_local_link = sprintf( '<a href="%s">%s &raquo;</a>', 'https://deliciousbrains.com/wp-offload-s3/doc/compatibility-with-other-plugins/', __( 'More info', 'amazon-s3-and-cloudfront' ) );
155
  $remove_local_msg = apply_filters( 'as3cf_remove_local_notice', sprintf( __( '<strong>Warning</strong> &mdash; Some plugins depend on the file being present on the local server and may not work when the file is removed. %s', 'amazon-s3-and-cloudfront' ), $remove_local_link ) );
156
  $remove_local_args = array(
157
  'message' => $remove_local_msg,
@@ -163,46 +205,23 @@ $selected_bucket_prefix = $this->get_object_prefix(); ?>
163
  $this->render_view( 'notice', $remove_local_args ); ?>
164
  </td>
165
  </tr>
166
- <tr class="advanced-options url-preview">
 
167
  <td>
168
- <?php $this->render_view( 'checkbox', array( 'key' => 'object-versioning' ) ); ?>
169
  </td>
170
  <td>
 
171
  <h4><?php _e( 'Object Versioning', 'amazon-s3-and-cloudfront' ) ?></h4>
172
  <p>
173
  <?php _e( 'Append a timestamp to the S3 file path. Recommended when using CloudFront so you don\'t have to worry about cache invalidation.' ); ?>
174
- <a href="http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ReplacingObjects.html">
175
- <?php _e( 'More info', 'amazon-s3-and-cloudfront' ) ?> &raquo;
176
- </a>
177
  </p>
178
  </td>
179
  </tr>
180
- <tr class="advanced-options">
181
- <td>
182
- <?php $this->render_view( 'checkbox', array( 'key' => 'expires' ) ); ?>
183
- </td>
184
- <td>
185
- <h4><?php _e( 'Far Future Expiration Header', 'amazon-s3-and-cloudfront' ) ?></h4>
186
- <p><?php _e( 'Implements a "Never Expire" caching policy for browsers by setting an Expires header for 10 years in the future. Should be used in conjunction with object versioning above.' ); ?>
187
- <a href="http://developer.yahoo.com/performance/rules.html#expires">
188
- <?php _e( 'More info', 'amazon-s3-and-cloudfront' ) ?> &raquo;
189
- </a>
190
- </p>
191
- </td>
192
- </tr>
193
- <tr class="advanced-options as3cf-border-bottom">
194
- <td>
195
- <?php $this->render_view( 'checkbox', array( 'key' => 'hidpi-images' ) ); ?>
196
- </td>
197
- <td>
198
- <h4><?php _e( 'Copy HiDPI (@2x) Images', 'amazon-s3-and-cloudfront' ) ?></h4>
199
- <p> <?php printf( __( 'When uploading a file to S3, checks if there\'s a file of the same name with an @2x suffix and copies it to S3 as well. Works with the <a href="%s">WP Retina 2x</a> plugin.', 'amazon-s3-and-cloudfront' ), 'https://wordpress.org/plugins/wp-retina-2x/' ); ?></p>
200
- </td>
201
- </tr>
202
-
203
  </table>
204
  <p>
205
- <button type="submit" class="button button-primary"><?php _e( 'Save Changes', 'amazon-s3-and-cloudfront' ); ?></button>
206
  </p>
207
  </form>
208
  </div>
22
  </div>
23
 
24
  <?php
25
+ do_action( 'as3cf_pre_tab_render', 'media' );
26
  $this->render_bucket_permission_errors(); ?>
27
 
28
  <div class="as3cf-main-settings">
39
  'prefix' => $prefix,
40
  'selected_bucket' => $selected_bucket,
41
  'selected_bucket_prefix' => $selected_bucket_prefix,
42
+ 'tr_class' => 'as3cf-border-bottom as3cf-bucket-setting',
43
  )
44
  ); ?>
45
+
46
+ <?php $args = $this->get_setting_args( 'copy-to-s3' ); ?>
47
  <tr class="as3cf-setting-title">
48
  <td colspan="2"><h3><?php _e( 'Enable/Disable the Plugin', 'amazon-s3-and-cloudfront' ); ?></h3></td>
49
  </tr>
50
+ <tr class="<?php echo $args['tr_class']; ?>">
51
  <td>
52
+ <?php $this->render_view( 'checkbox', $args ); ?>
53
  </td>
54
  <td>
55
+ <?php echo $args['setting_msg']; ?>
56
  <h4><?php _e( 'Copy Files to S3', 'amazon-s3-and-cloudfront' ) ?></h4>
57
+ <p>
58
+ <?php _e( 'When a file is uploaded to the Media Library, copy it to S3. Existing files are <em>not</em> copied to S3.', 'amazon-s3-and-cloudfront' ); ?>
59
+ <?php echo $this->settings_more_info_link( 'copy-to-s3' ); ?>
60
+ </p>
61
+
62
  </td>
63
  </tr>
64
+ <?php $args = $this->get_setting_args( 'serve-from-s3' ); ?>
65
+ <tr class="as3cf-border-bottom <?php echo $args['tr_class']; ?>">
66
  <td>
67
+ <?php $this->render_view( 'checkbox', $args ); ?>
68
  </td>
69
  <td>
70
+ <?php echo $args['setting_msg']; ?>
71
  <h4><?php _e( 'Rewrite File URLs', 'amazon-s3-and-cloudfront' ) ?></h4>
72
+ <p>
73
+ <?php _e( 'For Media Library files that have been copied to S3, rewrite the URLs so that they are served from S3/CloudFront instead of your server.', 'amazon-s3-and-cloudfront' ); ?>
74
+ <?php echo $this->settings_more_info_link( 'serve-from-s3' ); ?>
75
+ </p>
76
+
77
  </td>
78
  </tr>
79
  <tr class="configure-url as3cf-setting-title">
89
  </div>
90
  </td>
91
  </tr>
92
+ <?php $this->render_view( 'domain-setting' ); ?>
93
+ <?php $args = $this->get_setting_args( 'enable-object-prefix' ); ?>
94
+ <tr class="configure-url url-preview <?php echo $args['tr_class']; ?>">
95
  <td>
96
+ <?php $args['class'] = 'sub-toggle'; ?>
97
+ <?php $this->render_view( 'checkbox', $args ); ?>
98
  </td>
99
  <td>
100
+ <?php echo $args['setting_msg']; ?>
101
  <h4><?php _e( 'Path', 'amazon-s3-and-cloudfront' ) ?></h4>
102
  <p class="object-prefix-desc">
103
+ <?php _e( 'By default the path is the same as your local WordPress files.', 'amazon-s3-and-cloudfront' ); ?>
104
+ <?php echo $this->settings_more_info_link( 'object-prefix' ); ?>
105
  </p>
106
  <p class="as3cf-setting enable-object-prefix <?php echo ( $this->get_setting( 'enable-object-prefix' ) ) ? '' : 'hide'; // xss ok ?>">
107
+ <?php
108
+ $args = $this->get_setting_args( 'object-prefix' );
109
+ if ( false === $this->get_defined_setting( 'object-prefix', false ) ) {
110
+ $placeholder = 'placeholder="placeholder"';
111
+ } else {
112
+ $placeholder = '';
113
+ }
114
+ ?>
115
+ <input type="text" name="object-prefix" value="<?php echo esc_attr( $this->get_setting( 'object-prefix' ) ); ?>" size="30" placeholder="<?php echo $placeholder; ?>" <?php echo $args['disabled_attr']; ?> />
116
  </p>
117
  </td>
118
  </tr>
119
+
120
+ <?php $args = $this->get_setting_args( 'use-yearmonth-folders' ); ?>
121
+ <tr class="configure-url url-preview <?php echo $args['tr_class']; ?>">
122
  <td>
123
+ <?php $this->render_view( 'checkbox', $args ); ?>
124
  </td>
125
  <td>
126
+ <?php echo $args['setting_msg']; ?>
127
  <h4><?php _e( 'Year/Month', 'amazon-s3-and-cloudfront' ) ?></h4>
128
  <p>
129
  <?php _e( 'Add the Year/Month in the URL.' ); ?>
130
+ <?php echo $this->settings_more_info_link( 'use-yearmonth-folders' ); ?>
131
  </p>
132
  </td>
133
  </tr>
134
+
135
+ <?php $args = $this->get_setting_args( 'ssl' ); ?>
136
+ <tr class="configure-url as3cf-border-bottom url-preview <?php echo $args['tr_class']; ?>">
137
  <td>
138
+ <h4><?php _e( 'SSL', 'amazon-s3-and-cloudfront' ); ?></h4>
139
  </td>
140
  <td>
141
+ <p>
142
+ <?php _e( 'Controls the protocol of the S3 URLs.' ); ?>
143
+ <?php echo $this->settings_more_info_link( 'ssl' ); ?>
144
+ </p>
145
  <?php
146
+ $ssl = $this->get_setting( 'ssl' );
147
+ echo $args['setting_msg'];
148
+ ?>
149
  <div class="as3cf-ssl as3cf-radio-group">
150
  <label>
151
+ <input type="radio" name="ssl" value="request" <?php checked( $ssl, 'request' ); ?> <?php echo $args['disabled_attr']; ?>>
152
  <?php _e( 'Same as request', 'amazon-s3-and-cloudfront' ); ?>
153
  <p><?php _e( 'When the request is https://, use https:// for the file URL as well.', 'amazon-s3-and-cloudfront' ); ?></p>
154
  </label>
155
  <label>
156
+ <input type="radio" name="ssl" value="https" <?php checked( $ssl, 'https' ); ?> <?php echo $args['disabled_attr']; ?>>
157
  <?php _e( 'Always SSL', 'amazon-s3-and-cloudfront' ); ?>
158
  <p><?php _e( 'Forces https:// to be used.', 'amazon-s3-and-cloudfront' ); ?></p>
159
+ <?php if ( $this->show_deprecated_domain_setting() ) : ?>
160
+ <p><?php _e( 'You cannot use the "Bucket as a subdomain" domain option when using SSL.', 'amazon-s3-and-cloudfront' ); ?></p>
161
+ <?php endif; ?>
162
+ </label>
163
  <label>
164
+ <input type="radio" name="ssl" value="http" <?php checked( $ssl, 'http' ); ?> <?php echo $args['disabled_attr']; ?>>
165
  <?php _e( 'Always non-SSL', 'amazon-s3-and-cloudfront' ); ?>
166
  <p><?php _e( 'Forces http:// to be used.', 'amazon-s3-and-cloudfront' ); ?></p>
167
  </label>
171
  <tr class="advanced-options as3cf-setting-title">
172
  <td colspan="2"><h3><?php _e( 'Advanced Options', 'amazon-s3-and-cloudfront' ); ?></h3></td>
173
  </tr>
174
+ <?php $args = $this->get_setting_args( 'remove-local-file' ); ?>
175
+ <tr class="advanced-options <?php echo $args['tr_class']; ?>">
176
  <td>
177
+ <?php $this->render_view( 'checkbox', $args ); ?>
178
  </td>
179
  <td>
180
+ <?php echo $args['setting_msg']; ?>
181
  <h4><?php _e( 'Remove Files From Server', 'amazon-s3-and-cloudfront' ) ?></h4>
182
+ <p><?php _e( 'Once a file has been copied to S3, remove it from the local server.', 'amazon-s3-and-cloudfront' ); ?>
183
+ <?php echo $this->settings_more_info_link( 'remove-local-file' ); ?>
184
+ </p>
185
  <?php
186
  $lost_files_msg = apply_filters( 'as3cf_lost_files_notice', __( '<strong>Broken URLs</strong> &mdash; There will be broken URLs for files that don\'t exist locally. You can fix this by enabling <strong>Rewrite File URLs</strong> to use the S3 URLs.', 'amazon-s3-and-cloudfront' ) );
187
  $lost_files_args = array(
193
  );
194
  $this->render_view( 'notice', $lost_files_args );
195
 
196
+ $remove_local_link = $this->more_info_link( 'https://deliciousbrains.com/wp-offload-s3/doc/compatibility-with-other-plugins/' );
197
  $remove_local_msg = apply_filters( 'as3cf_remove_local_notice', sprintf( __( '<strong>Warning</strong> &mdash; Some plugins depend on the file being present on the local server and may not work when the file is removed. %s', 'amazon-s3-and-cloudfront' ), $remove_local_link ) );
198
  $remove_local_args = array(
199
  'message' => $remove_local_msg,
205
  $this->render_view( 'notice', $remove_local_args ); ?>
206
  </td>
207
  </tr>
208
+ <?php $args = $this->get_setting_args( 'object-versioning' ); ?>
209
+ <tr class="advanced-options url-preview as3cf-border-bottom <?php echo $args['tr_class']; ?>">
210
  <td>
211
+ <?php $this->render_view( 'checkbox', $args ); ?>
212
  </td>
213
  <td>
214
+ <?php echo $args['setting_msg']; ?>
215
  <h4><?php _e( 'Object Versioning', 'amazon-s3-and-cloudfront' ) ?></h4>
216
  <p>
217
  <?php _e( 'Append a timestamp to the S3 file path. Recommended when using CloudFront so you don\'t have to worry about cache invalidation.' ); ?>
218
+ <?php echo $this->settings_more_info_link( 'object-versioning' ); ?>
 
 
219
  </p>
220
  </td>
221
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  </table>
223
  <p>
224
+ <button type="submit" class="button button-primary" <?php echo $this->maybe_disable_save_button(); ?>><?php _e( 'Save Changes', 'amazon-s3-and-cloudfront' ); ?></button>
225
  </p>
226
  </form>
227
  </div>
wordpress-s3.php CHANGED
@@ -1,10 +1,10 @@
1
  <?php
2
  /*
3
- Plugin Name: WP Offload S3
4
  Plugin URI: http://wordpress.org/extend/plugins/amazon-s3-and-cloudfront/
5
  Description: Automatically copies media uploads to Amazon S3 for storage and delivery. Optionally configure Amazon CloudFront for even faster delivery.
6
  Author: Delicious Brains
7
- Version: 0.9.11
8
  Author URI: http://deliciousbrains.com/
9
  Network: True
10
  Text Domain: amazon-s3-and-cloudfront
@@ -26,18 +26,18 @@ Domain Path: /languages/
26
  // Then completely rewritten.
27
  */
28
 
29
- $GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['version'] = '0.9.11';
30
 
31
- $GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['supported_addon_versions'] = array(
32
- 'amazon-s3-and-cloudfront-pro' => '1.0b1',
33
- );
 
34
 
35
- $aws_plugin_version_required = '0.3.4';
36
 
37
- require dirname( __FILE__ ) . '/classes/wp-aws-compatibility-check.php';
38
  global $as3cf_compat_check;
39
  $as3cf_compat_check = new WP_AWS_Compatibility_Check(
40
- 'WP Offload S3',
41
  'amazon-s3-and-cloudfront',
42
  __FILE__,
43
  'Amazon Web Services',
@@ -47,6 +47,11 @@ $as3cf_compat_check = new WP_AWS_Compatibility_Check(
47
 
48
  function as3cf_init( $aws ) {
49
  global $as3cf_compat_check;
 
 
 
 
 
50
  if ( ! $as3cf_compat_check->is_compatible() ) {
51
  return;
52
  }
@@ -54,6 +59,7 @@ function as3cf_init( $aws ) {
54
  global $as3cf;
55
  $abspath = dirname( __FILE__ );
56
  require_once $abspath . '/include/functions.php';
 
57
  require_once $abspath . '/classes/as3cf-upgrade.php';
58
  require_once $abspath . '/classes/upgrades/as3cf-region-meta.php';
59
  require_once $abspath . '/classes/upgrades/as3cf-file-sizes.php';
1
  <?php
2
  /*
3
+ Plugin Name: WP Offload S3 Lite
4
  Plugin URI: http://wordpress.org/extend/plugins/amazon-s3-and-cloudfront/
5
  Description: Automatically copies media uploads to Amazon S3 for storage and delivery. Optionally configure Amazon CloudFront for even faster delivery.
6
  Author: Delicious Brains
7
+ Version: 1.0
8
  Author URI: http://deliciousbrains.com/
9
  Network: True
10
  Text Domain: amazon-s3-and-cloudfront
26
  // Then completely rewritten.
27
  */
28
 
29
+ $GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['version'] = '1.0';
30
 
31
+ $aws_plugin_version_required = '0.3.5';
32
+
33
+ require_once dirname( __FILE__ ) . '/classes/wp-aws-compatibility-check.php';
34
+ require_once dirname( __FILE__ ) . '/classes/as3cf-utils.php';
35
 
36
+ add_action( 'activated_plugin', array( 'AS3CF_Utils', 'deactivate_other_instances' ) );
37
 
 
38
  global $as3cf_compat_check;
39
  $as3cf_compat_check = new WP_AWS_Compatibility_Check(
40
+ 'WP Offload S3 Lite',
41
  'amazon-s3-and-cloudfront',
42
  __FILE__,
43
  'Amazon Web Services',
47
 
48
  function as3cf_init( $aws ) {
49
  global $as3cf_compat_check;
50
+ if ( $as3cf_compat_check->is_plugin_active( 'amazon-s3-and-cloudfront-pro/amazon-s3-and-cloudfront-pro.php' ) ) {
51
+ // Don't load if pro plugin installed
52
+ return;
53
+ }
54
+
55
  if ( ! $as3cf_compat_check->is_compatible() ) {
56
  return;
57
  }
59
  global $as3cf;
60
  $abspath = dirname( __FILE__ );
61
  require_once $abspath . '/include/functions.php';
62
+ require_once $abspath . '/classes/as3cf-error.php';
63
  require_once $abspath . '/classes/as3cf-upgrade.php';
64
  require_once $abspath . '/classes/upgrades/as3cf-region-meta.php';
65
  require_once $abspath . '/classes/upgrades/as3cf-file-sizes.php';