WP Offload S3 Lite - Version 0.9.1

Version Description

  • 2015-07-29- =
  • Improvement: Access denied sample IAM policy replaced with link to Quick Start Guide
  • Improvement: Access denied messages on bucket selection or bucket creation now link to Quick Start Guide
  • Improvement: Object expires time can now be filtered using the as3cf_object_meta filter
  • Bug fix: Error not always shown when S3 bucket inaccessible due to incorrect permissions
  • Bug fix: Permission checks fail when S3 bucket is in a non-default region and defined by AS3CF_BUCKET constant
  • Bug fix: Restore as3cf_get_attached_file_copy_back_to_local filter
  • Bug fix: Image versions not uploaded to S3 when an edited image is restored
  • Bug fix: Original image version not deleted from server when Remove Files From Server option enabled
  • Bug fix: Media library items with non-ascii characters in the file name are not removed from S3
  • Bug fix: Compatibility notices shown on plugin install pages
  • Bug fix: WordPress footer overlaps WP Offload S3 sidebar
  • Bug fix: Upon initial setup the settings changed alert shows when no settings have changed
Download this release

Release Info

Developer bradt
Plugin Icon 128x128 WP Offload S3 Lite
Version 0.9.1
Comparing to
See all releases

Code changes from version 0.9 to 0.9.1

CONTRIBUTING.md CHANGED
@@ -9,12 +9,13 @@ Submit a ticket for your issue, assuming one does not already exist.
9
 
10
  ## Making Changes
11
 
12
- * Fork the repository on GitHub
13
- * From the `develop` branch on your forked repository, create a new branch and make your changes
14
  * It is suggested that your new branch use a name that briefly describes the feature or issue.
15
- * Ensure you stick to the [WordPress Coding Standards](http://codex.wordpress.org/WordPress_Coding_Standards)
16
- * When committing, use a [well-formed](http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message) [commit](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) [message](http://who-t.blogspot.com/2009/12/on-commit-messages.html)
17
- * Push the changes to your fork and submit a pull request to the `develop` branch of the plugin's repository
 
18
 
19
  ## Code Documentation
20
 
9
 
10
  ## Making Changes
11
 
12
+ * Fork the repository on GitHub.
13
+ * From the `master` branch on your forked repository, create a new branch and make your changes.
14
  * It is suggested that your new branch use a name that briefly describes the feature or issue.
15
+ * Ensure you stick to the [WordPress Coding Standards](http://codex.wordpress.org/WordPress_Coding_Standards).
16
+ * When committing, use a [well-formed](http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message) [commit](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) [message](http://who-t.blogspot.com/2009/12/on-commit-messages.html).
17
+ * Push the changes to your fork and submit a pull request to the `master` branch of the plugin's repository.
18
+ * We appreciate any pull requests, however, as development on this plugin actually takes place in private repo, no PRs will be merged here. Although we will give props for code that gets released.
19
 
20
  ## Code Documentation
21
 
README.md CHANGED
@@ -3,8 +3,8 @@
3
  **Donate link:** https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5VPMGLLK94XJC
4
  **Tags:** uploads, amazon, s3, mirror, admin, media, cdn, cloudfront
5
  **Requires at least:** 3.5
6
- **Tested up to:** 4.2.2
7
- **Stable tag:** 0.9
8
  **License:** GPLv3
9
 
10
  Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery.
@@ -63,6 +63,20 @@ This version requires PHP 5.3.3+ and the Amazon Web Services plugin
63
 
64
  ## Changelog ##
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  ### 0.9 - 2015-07-08 ###
67
  * New: Plugin rebranded to WP Offload S3
68
  * New: Support tab added to _Offload S3_ screen containing diagnostic information
3
  **Donate link:** https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5VPMGLLK94XJC
4
  **Tags:** uploads, amazon, s3, mirror, admin, media, cdn, cloudfront
5
  **Requires at least:** 3.5
6
+ **Tested up to:** 4.3
7
+ **Stable tag:** 0.9.1
8
  **License:** GPLv3
9
 
10
  Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery.
63
 
64
  ## Changelog ##
65
 
66
+ ### 0.9.1 - 2015-07-29- ###
67
+ * Improvement: Access denied sample IAM policy replaced with link to [Quick Start Guide](https://deliciousbrains.com/wp-offload-s3/doc/quick-start-guide/)
68
+ * Improvement: Access denied messages on bucket selection or bucket creation now link to [Quick Start Guide](https://deliciousbrains.com/wp-offload-s3/doc/quick-start-guide/)
69
+ * Improvement: Object expires time can now be filtered using the `as3cf_object_meta` filter
70
+ * Bug fix: Error not always shown when S3 bucket inaccessible due to incorrect permissions
71
+ * Bug fix: Permission checks fail when S3 bucket is in a non-default region and defined by `AS3CF_BUCKET` constant
72
+ * Bug fix: Restore `as3cf_get_attached_file_copy_back_to_local` filter
73
+ * Bug fix: Image versions not uploaded to S3 when an edited image is restored
74
+ * Bug fix: Original image version not deleted from server when _Remove Files From Server_ option enabled
75
+ * Bug fix: Media library items with non-ascii characters in the file name are not removed from S3
76
+ * Bug fix: Compatibility notices shown on plugin install pages
77
+ * Bug fix: WordPress footer overlaps WP Offload S3 sidebar
78
+ * Bug fix: Upon initial setup the settings changed alert shows when no settings have changed
79
+
80
  ### 0.9 - 2015-07-08 ###
81
  * New: Plugin rebranded to WP Offload S3
82
  * New: Support tab added to _Offload S3_ screen containing diagnostic information
assets/css/modal.css CHANGED
@@ -1 +1 @@
1
- #as3cf-overlay{display:none;position:fixed;top:0;right:0;bottom:0;left:0;background-color:rgba(0,0,0,0.5);overflow:hidden;overflow-y:auto;z-index:999999}#as3cf-modal{display:none;position:relative;width:600px;margin:100px auto;padding:30px;background-color:#eee;box-shadow:0 0 10px rgba(0,0,0,0.5);font-size:14px;overflow:hidden;z-index:100000}#as3cf-modal .close-as3cf-modal{color:#999;cursor:pointer;font-family:"Times New Roman", serif;font-size:26px;font-weight:200;position:absolute;right:18px;top:18px}#as3cf-modal .close-as3cf-modal:hover{color:#666}#as3cf-modal h3{margin:0 0 20px;font-weight:normal;line-height:1}#as3cf-modal .error,#as3cf-modal .notice,#as3cf-modal .updated{margin:0 0 20px}#as3cf-modal .actions{margin:20px -30px -30px;padding:20px 30px;border-top:none;background-color:#e3e3e3;overflow:hidden}#as3cf-modal .actions .right{margin-left:15px}#as3cf-modal .actions .right:last-of-type{margin-left:0}#as3cf-modal .actions button{min-width:90px}body.as3cf-modal-open{overflow:hidden;padding-right:15px}
1
+ #as3cf-overlay{display:none;position:fixed;top:0;right:0;bottom:0;left:0;background-color:rgba(0,0,0,0.5);overflow:hidden;overflow-y:auto;z-index:999999}#as3cf-modal{display:none;position:relative;width:600px;margin:100px auto;padding:30px;background-color:#eee;box-shadow:0 0 10px rgba(0,0,0,0.5);font-size:14px;overflow:hidden;z-index:100000}#as3cf-modal .close-as3cf-modal{color:#999;cursor:pointer;font-family:"Times New Roman", serif;font-size:26px;font-weight:200;position:absolute;right:18px;top:18px}#as3cf-modal .close-as3cf-modal:hover{color:#666}#as3cf-modal h3{margin:0 0 20px;font-weight:normal;line-height:1}#as3cf-modal .error,#as3cf-modal .notice,#as3cf-modal .updated{margin:0 0 20px}#as3cf-modal .actions{margin:20px -30px -30px;padding:20px 30px;border-top:none;background-color:#e3e3e3;overflow:hidden}#as3cf-modal .actions .right{margin-left:15px}#as3cf-modal .actions .right:last-of-type{margin-left:0}#as3cf-modal .actions button{min-width:90px}body.as3cf-modal-open{overflow:hidden}
assets/css/styles.css CHANGED
@@ -1 +1 @@
1
- .aws-main.wrap>h2{float:left}.aws-main.wrap .as3cf-notice,.aws-main.wrap .as3cf-updated,.aws-main.wrap .as3cf-error{margin-bottom:0;-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:0;width:650px;margin-top:10px;padding-left:5px;padding-right:0}.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"] .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 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 .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 .as3cf-invalid-bucket-name{font-size:12px;color:#a00}.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 .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 ul{margin-left:20px;list-style-type:disc}.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.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@2x.jpg);background-size:292px 165px;width:292px;height:165px;display:block}.as3cf-sidebar .as3cf-banner img{display:none}}@media screen and (max-width: 1052px){.as3cf-sidebar{position:relative;top:auto;right:auto;margin-top:50px}}.as3cf-banner img{display:block}.aws-compatibility-notice.error{clear:both;margin:5px 20px 5px 0}
1
+ .aws-main.wrap>h2{float:left}.aws-main.wrap .as3cf-notice,.aws-main.wrap .as3cf-updated,.aws-main.wrap .as3cf-error{margin-bottom:0;-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:0;width:650px;margin-top:10px;padding-left:5px;padding-right:0}.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 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 .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 .as3cf-invalid-bucket-name{font-size:12px;color:#a00}.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}
assets/img/snail-banner.jpg ADDED
Binary file
assets/img/snail-banner@2x.jpg ADDED
Binary file
assets/img/snail.jpg DELETED
Binary file
assets/img/snail@2x.jpg DELETED
Binary file
assets/js/script.js CHANGED
@@ -33,6 +33,7 @@
33
  }
34
 
35
  as3cf.tabs = {
 
36
  /**
37
  * Toggle settings tab
38
  *
@@ -56,285 +57,424 @@
56
  };
57
 
58
  /**
59
- * Load bucket list
60
- *
61
- * @param bool forceUpdate
62
  */
63
- function loadBucketList( forceUpdate ) {
64
- if ( 'undefined' === typeof forceUpdate ) {
65
- forceUpdate = false;
66
- }
67
-
68
- var $bucketList = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-bucket-list' );
69
- var selectedBucket = $( '#' + as3cfModal.prefix + '-bucket' ).val();
70
-
71
- if ( false === forceUpdate && $bucketList.find( 'li' ).length > 1 ) {
72
- $( '.as3cf-bucket-list a' ).removeClass( 'selected' );
73
- $( '.as3cf-bucket-list a[data-bucket="' + selectedBucket + '"]' ).addClass( 'selected' );
74
 
75
- scrollToSelectedBucket();
76
- return;
77
- }
 
78
 
79
- $bucketList.html( '<li class="loading">' + $bucketList.attr( 'data-working' ) + '</li>' );
 
 
 
80
 
81
- var data = {
82
- action: as3cfModal.prefix + '-get-buckets',
83
- _nonce: window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.get_buckets
84
- };
 
 
 
 
 
85
 
86
- $.ajax( {
87
- url: ajaxurl,
88
- type: 'POST',
89
- dataType: 'JSON',
90
- data: data,
91
- error: function( jqXHR, textStatus, errorThrown ) {
92
- $bucketList.html( '' );
93
- showBucketError( as3cf.strings.get_buckets_error, errorThrown, 'as3cf-bucket-select' );
94
- },
95
- success: function( data, textStatus, jqXHR ) {
96
- $bucketList.html( '' );
97
 
98
- if ( typeof data[ 'success' ] !== 'undefined' ) {
99
- $( '.as3cf-bucket-error' ).hide();
 
100
 
101
- $( data[ 'buckets' ] ).each( function( idx, bucket ) {
102
- var bucketClass = bucket.Name === selectedBucket ? 'selected' : '';
103
- $bucketList.append( '<li><a class="' + bucketClass + '" href="#" data-bucket="' + bucket.Name + '"><span class="bucket"><span class="dashicons dashicons-portfolio"></span> ' + bucket.Name + '</span><span class="spinner"></span></span></a></li>' );
104
- } );
105
 
106
- scrollToSelectedBucket();
107
- } else {
108
- showBucketError( as3cf.strings.get_buckets_error, data[ 'error' ], 'as3cf-bucket-select' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  }
 
 
 
 
 
 
 
 
 
110
  }
111
- } );
112
- }
113
 
114
- /**
115
- * Scroll to selected bucket
116
- */
117
- function scrollToSelectedBucket() {
118
- if ( !$( '.as3cf-bucket-list a.selected' ).length ) {
119
- return;
120
- }
121
 
122
- var offset = $( 'ul.as3cf-bucket-list li' ).first().position().top + 150;
 
 
 
123
 
124
- $( '.as3cf-bucket-list' ).animate( {
125
- scrollTop: $( 'ul.as3cf-bucket-list li a.selected' ).position().top - offset
126
- } );
127
- }
 
128
 
129
- /**
130
- * Reset bucket modal
131
- */
132
- function resetBucketModal() {
133
- var $bucketContainer = $( '.as3cf-bucket-container.' + as3cfModal.prefix );
 
134
 
135
- if ( false === $activeTab.hasClass( 'as3cf-has-bucket' ) || 'manual' === $( '#' + as3cfModal.prefix + '-bucket-select' ).val() ) {
136
- $bucketContainer.find( '.as3cf-bucket-manual' ).show().siblings().hide();
137
- $bucketContainer.find( '.bucket-actions.manual' ).show().siblings( '.bucket-actions' ).hide();
138
- } else {
139
- $bucketContainer.find( '.as3cf-bucket-select' ).show().siblings().hide();
140
- $bucketContainer.find( '.bucket-actions.select' ).show().siblings( '.bucket-actions' ).hide();
141
 
142
- loadBucketList();
143
- }
144
 
145
- $bucketContainer.find( '.as3cf-bucket-error' ).hide();
 
 
146
 
147
- // Reset manual select value
148
- var bucket = $( '#' + as3cfModal.prefix + '-bucket' ).val();
149
- $bucketContainer.find( '.as3cf-bucket-manual .as3cf-bucket-name' ).val( bucket );
150
- }
151
 
152
- /**
153
- * Save manual bucket
154
- */
155
- function saveManualBucket() {
156
- var $manualBucketForm = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-manual-save-bucket-form' );
157
- var $manualBucketInput = $manualBucketForm.find( '.as3cf-bucket-name' );
158
- var $manualBucketButton = $manualBucketForm.find( 'button[type=submit]' );
159
- var bucketName = $manualBucketInput.val();
160
- var originalBucketText = $manualBucketButton.first().text();
161
-
162
- if ( bucketName === $( '#' + as3cfModal.prefix + '-active-bucket' ).text() ) {
 
 
 
 
 
163
  $( '.as3cf-bucket-error' ).hide();
164
- $activeTab.addClass( 'as3cf-has-bucket' );
165
- as3cfModal.close();
166
- return;
167
- }
168
- $( '.as3cf-bucket-error' ).hide();
169
- $manualBucketButton.text( $manualBucketButton.attr( 'data-working' ) );
170
- $manualBucketButton.prop( 'disabled', true );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
 
172
- var data = {
173
- action: as3cfModal.prefix + '-manual-save-bucket',
174
- bucket_name: bucketName,
175
- _nonce: window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.manual_bucket
176
- };
 
 
177
 
178
- $.ajax( {
179
- url: ajaxurl,
180
- type: 'POST',
181
- dataType: 'JSON',
182
- data: data,
183
- error: function( jqXHR, textStatus, errorThrown ) {
184
- $manualBucketButton.text( originalBucketText );
185
- showBucketError( as3cf.strings.save_bucket_error, errorThrown, 'as3cf-bucket-manual' );
186
- },
187
- success: function( data, textStatus, jqXHR ) {
188
- $manualBucketButton.text( originalBucketText );
189
- $manualBucketButton.prop( 'disabled', false );
190
- if ( typeof data[ 'success' ] !== 'undefined' ) {
191
- bucketSelect( bucketName, data[ 'region' ], data[ 'can_write' ] );
192
- $( '#' + as3cfModal.prefix + '-bucket-select' ).val( 'manual' );
193
- $( '.as3cf-bucket-list a' ).removeClass( 'selected' ).filter( '[data-bucket=' + bucketName + ']' ).addClass( 'selected' );
194
- } else {
195
- showBucketError( as3cf.strings.save_bucket_error, data[ 'error' ], 'as3cf-bucket-manual' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  }
 
 
 
 
 
 
 
 
 
197
  }
198
- } );
199
- }
200
 
201
- /**
202
- * Save select bucket
203
- *
204
- * @param object $link
205
- */
206
- function saveSelectBucket( $link ) {
207
- var $bucketList = $( '.as3cf-bucket-list' );
208
 
209
- if ( $link.hasClass( 'selected' ) ) {
210
- $activeTab.addClass( 'as3cf-has-bucket' );
211
- as3cfModal.close();
212
- return;
213
- }
 
214
 
215
- var previousBucket = $( '.as3cf-bucket-list a.selected' ).attr( 'data-bucket' );
 
 
 
 
 
 
216
 
217
- $( '.as3cf-bucket-list a' ).removeClass( 'selected' );
218
- $link.addClass( 'selected' );
 
 
 
 
 
 
 
 
219
 
220
- $bucketList.addClass( 'saving' );
221
- $link.find( '.spinner' ).show().css( 'visibility', 'visible' );
222
- var bucketName = $link.attr( 'data-bucket' );
223
 
224
- var data = {
225
- action: as3cfModal.prefix + '-save-bucket',
226
- bucket_name: bucketName,
227
- _nonce: window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.save_bucket
228
- };
229
 
230
- $.ajax( {
231
- url: ajaxurl,
232
- type: 'POST',
233
- dataType: 'JSON',
234
- data: data,
235
- error: function( jqXHR, textStatus, errorThrown ) {
236
- $bucketList.removeClass( 'saving' );
237
- showBucketError( as3cf.strings.save_bucket_error, errorThrown, 'as3cf-bucket-select' );
238
- $( '.as3cf-bucket-list a' ).removeClass( 'selected' );
239
- $( '.as3cf-bucket-list a[data-bucket="' + previousBucket + '"]' ).addClass( 'selected' );
240
- },
241
- success: function( data, textStatus, jqXHR ) {
242
- $link.find( '.spinner' ).hide().css( 'visibility', 'hidden' );
243
- $bucketList.removeClass( 'saving' );
244
- if ( typeof data[ 'success' ] !== 'undefined' ) {
245
- bucketSelect( bucketName, data[ 'region' ], data[ 'can_write' ] );
246
- $( '#' + as3cfModal.prefix + '-bucket-select' ).val( '' );
247
- } else {
248
- showBucketError( as3cf.strings.save_bucket_error, data[ 'error' ], 'as3cf-bucket-select' );
249
- $( '.as3cf-bucket-list a' ).removeClass( 'selected' );
250
- $( '.as3cf-bucket-list a[data-bucket="' + previousBucket + '"]' ).addClass( 'selected' );
251
- }
 
 
 
 
 
252
  }
253
- } );
254
- }
255
 
256
- /**
257
- * Disable bucket buttons
258
- */
259
- function disableBucketButtons() {
260
- if ( 0 === $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-create-bucket-form' ).length ) {
261
- return;
262
- }
263
 
264
- var $createBucketForm = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-create-bucket-form' );
265
- var $manualBucketForm = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-manual-save-bucket-form' );
 
 
266
 
267
- if ( $createBucketForm.find( '.as3cf-bucket-name' ).val().length < 3 ) {
268
- $createBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
269
- }
270
- else {
271
- $createBucketForm.find( 'button[type=submit]' ).attr( 'disabled', false );
272
- }
273
 
274
- if ( $manualBucketForm.find( '.as3cf-bucket-name' ).val().length < 3 ) {
275
- $manualBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
276
- }
277
- else {
278
- $manualBucketForm.find( 'button[type=submit]' ).attr( 'disabled', false );
279
- }
280
- }
281
 
282
- /**
283
- * Show bucket error
284
- *
285
- * @param title
286
- * @param error
287
- * @param context
288
- */
289
- function showBucketError( title, error, context ) {
290
- var $activeView = $( '.as3cf-bucket-container' ).children( ':visible' );
291
- var $bucketError = $activeView.find( '.as3cf-bucket-error' );
292
 
293
- context = ( 'undefined' === typeof context ) ? null : context;
 
294
 
295
- if ( context && ! $activeView.hasClass( context ) ) {
296
- return;
297
- }
298
 
299
- $bucketError.find( 'span.title' ).html( title );
300
- $bucketError.find( 'span.message' ).html( error );
301
- $bucketError.show();
302
- }
 
303
 
304
- /**
305
- * Select bucket
306
- *
307
- * @param string title
308
- * @param string error
309
- * @param bool canWrite
310
- */
311
- function bucketSelect( bucket, region, canWrite ) {
312
- var $manualBucketForm = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-manual-save-bucket-form' );
313
- var $activeBucket = $( '#' + as3cfModal.prefix + '-active-bucket' );
314
-
315
- if ( 'as3cf' === as3cfModal.prefix && '' === $activeBucket.text() ) {
316
- // first time bucket select - enable main options by default
317
- setCheckbox( 'copy-to-s3-wrap' );
318
- setCheckbox( 'serve-from-s3-wrap' );
319
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
 
321
- $activeBucket.text( bucket );
322
- $manualBucketForm.find( '.as3cf-bucket-name' ).val( bucket );
323
- $( '#' + as3cfModal.prefix + '-bucket' ).val( bucket );
324
- $( '#' + as3cfModal.prefix + '-region' ).val( region );
325
- $( '.updated' ).not( '.as3cf-notice' ).show();
 
 
 
 
 
 
 
 
 
 
 
 
326
 
327
- $activeTab.addClass( 'as3cf-has-bucket' );
328
- // check permission on bucket
329
- $activeTab.find( '.as3cf-can-write-error' ).toggle( !canWrite );
330
- $activeTab.find( '.as3cf-bucket-error' ).hide();
331
 
332
- if ( 'as3cf' === as3cfModal.prefix ) {
333
- generateUrlPreview();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
  }
335
 
336
- as3cfModal.close();
337
- }
338
 
339
  /**
340
  * Generate URL preview
@@ -346,7 +486,7 @@
346
  _nonce: as3cf.nonces.get_url_preview
347
  };
348
 
349
- $.each( $( '#tab-media .as3cf-main-settings form' ).serializeArray(), function( i, o ) {
350
  var n = o.name,
351
  v = o.value;
352
  n = n.replace( '[]', '' );
@@ -375,99 +515,11 @@
375
  }
376
 
377
  /**
378
- * Check for a valid bucket name
379
- *
380
- * Bucket names must be at least 3 and no more than 63 characters long.
381
- * They can contain lowercase letters, numbers, periods and hyphens.
382
- *
383
- * @param string bucketName
384
- *
385
- * @return bool
386
- */
387
- function isValidBucketName( bucketName ) {
388
- if ( bucketName.length < 3 || bucketName.length > 63 ) {
389
- return false;
390
- }
391
- if ( true === bucketNamePattern.test( bucketName ) ) {
392
- return false;
393
- }
394
-
395
- return true;
396
- }
397
-
398
- /**
399
- * Update invalid bucket name notice
400
- *
401
- * @param string bucketName
402
- */
403
- function updateBucketNameNotice( bucketName ) {
404
- var message = null;
405
-
406
- if ( true === bucketNamePattern.test( bucketName ) ) {
407
- message = as3cf.strings.create_bucket_invalid_chars;
408
- } else if ( bucketName.length < 3 ) {
409
- message = as3cf.strings.create_bucket_name_short;
410
- } else if ( bucketName.length > 63 ) {
411
- message = as3cf.strings.create_bucket_name_long;
412
- }
413
-
414
- if ( message && bucketName.length > 0 ) {
415
- $( '.as3cf-invalid-bucket-name' ).html( message );
416
- } else {
417
- $( '.as3cf-invalid-bucket-name' ).html( '' );
418
- }
419
- }
420
-
421
- /**
422
- * Save create bucket
423
  */
424
- function saveCreateBucket() {
425
- var $createBucketForm = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-create-bucket-form' );
426
- var $createBucketInput = $createBucketForm.find( '.as3cf-bucket-name' );
427
- var $createBucketSelect = $createBucketForm.find( '.bucket-create-region' );
428
- var $createBucketButton = $createBucketForm.find( 'button[type=submit]' );
429
-
430
- var bucketName = $createBucketInput.val();
431
- var origButtonText = $createBucketButton.text();
432
-
433
- $( '.as3cf-bucket-error' ).hide();
434
- $createBucketButton.text( $createBucketButton.attr( 'data-working' ) );
435
- $createBucketButton.prop( 'disabled', true );
436
-
437
- var data = {
438
- action: as3cfModal.prefix + '-create-bucket',
439
- bucket_name: bucketName,
440
- _nonce: window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.create_bucket
441
- };
442
-
443
- if ( $createBucketSelect.val() ) {
444
- data[ 'region' ] = $createBucketSelect.val();
445
- }
446
-
447
- $.ajax( {
448
- url: ajaxurl,
449
- type: 'POST',
450
- dataType: 'JSON',
451
- data: data,
452
- error: function( jqXHR, textStatus, errorThrown ) {
453
- $createBucketButton.text( origButtonText );
454
- showBucketError( as3cf.strings.create_bucket_error, errorThrown, 'as3cf-bucket-create' );
455
- },
456
- success: function( data, textStatus, jqXHR ) {
457
- $createBucketButton.text( origButtonText );
458
- $createBucketButton.prop( 'disabled', false );
459
- if ( typeof data[ 'success' ] !== 'undefined' ) {
460
- bucketSelect( bucketName, data[ 'region' ], data[ 'can_write' ] );
461
- // tidy up create bucket form
462
- $( '.as3cf-bucket-select-region' ).hide();
463
- $( '.as3cf-bucket-select-region' ).removeAttr( 'selected' );
464
- $createBucketInput.val( '' );
465
- $createBucketButton.attr( 'disabled', true );
466
- } else {
467
- showBucketError( as3cf.strings.create_bucket_error, data[ 'error' ], 'as3cf-bucket-create' );
468
- }
469
- }
470
- } );
471
  }
472
 
473
  $( document ).ready( function() {
@@ -485,9 +537,8 @@
485
  as3cf.tabs.toggle( hash, true );
486
  } else {
487
  // default settings tab
488
- var defaultTab = 'media';
489
- $activeTab = $( '#tab-' + defaultTab );
490
- $( '.aws-main' ).attr( 'data-tab', defaultTab );
491
  }
492
 
493
  $( '.aws-main' ).on( 'click', '.nav-tab', function( e ) {
@@ -590,8 +641,7 @@
590
  $( 'body' ).on( 'click', '.bucket-action-browse', function( e ) {
591
  e.preventDefault();
592
  $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-bucket-select' ).show().siblings().hide();
593
-
594
- loadBucketList();
595
  } );
596
  $( 'body' ).on( 'click', '.bucket-action-create', function( e ) {
597
  e.preventDefault();
@@ -604,61 +654,70 @@
604
  } );
605
  $( 'body' ).on( 'click', '.bucket-action-cancel', function( e ) {
606
  e.preventDefault();
607
- resetBucketModal();
608
  } );
609
  $( 'body' ).on( 'click', '.bucket-action-save', function( e ) {
610
  e.preventDefault();
611
- saveManualBucket();
612
  } );
613
  $( 'body' ).on( 'click', '.as3cf-create-bucket-form button[type="submit"]', function( e ) {
614
  e.preventDefault();
615
- saveCreateBucket();
616
  } );
617
 
618
  // Bucket list refresh handler
619
  $( 'body' ).on( 'click', '.bucket-action-refresh', function( e ) {
620
  e.preventDefault();
621
- loadBucketList( true );
622
  } );
623
 
624
  // Bucket list click handler
625
  $( 'body' ).on( 'click', '.as3cf-bucket-list a', function( e ) {
626
  e.preventDefault();
627
- saveSelectBucket( $( this ) );
 
 
 
 
 
 
 
 
628
  } );
629
 
630
  // Modal open
631
  $( 'body' ).on( 'as3cf-modal-open', function( e, target ) {
632
  if ( '.as3cf-bucket-container.' + as3cfModal.prefix === target ) {
633
  // Reset modal
634
- resetBucketModal();
635
  // Change manual title text
636
  var title = $( '.as3cf-bucket-manual h3' ).data( 'modal-title' );
637
  $( '.as3cf-bucket-manual h3' ).text( title );
638
  // Hide buttons
639
- disableBucketButtons();
640
  }
641
  } );
642
- disableBucketButtons();
 
643
 
644
  // Validate bucket name on create
645
  $( 'body' ).on( 'input keyup', '.as3cf-create-bucket-form .as3cf-bucket-name', function( e ) {
646
  var bucketName = $( this ).val();
647
  var $createBucketForm = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-create-bucket-form' );
648
 
649
- if ( isValidBucketName( bucketName ) ) {
650
  $createBucketForm.find( 'button[type=submit]' ).removeAttr( 'disabled' );
651
  } else {
652
  $createBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
653
  }
654
- updateBucketNameNotice( bucketName );
655
  } );
656
 
657
  // Check bucket name length on manual
658
  $( 'body' ).on( 'input keyup', '.as3cf-manual-save-bucket-form .as3cf-bucket-name', function( e ) {
659
  var $manualBucketForm = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-manual-save-bucket-form' );
660
 
661
- if ( $manualBucketForm.find( '.as3cf-bucket-name' ).val().length < 3 ) {
662
  $manualBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
663
  } else {
664
  $manualBucketForm.find( 'button[type=submit]' ).removeAttr( 'disabled' );
33
  }
34
 
35
  as3cf.tabs = {
36
+ defaultTab: 'media',
37
  /**
38
  * Toggle settings tab
39
  *
57
  };
58
 
59
  /**
60
+ * Handle the bucket selection, either inline or in a modal
 
 
61
  */
62
+ as3cf.buckets = {
 
 
 
 
 
 
 
 
 
 
63
 
64
+ /**
65
+ * Buckets must be at least this many characters
66
+ */
67
+ validLength: 3,
68
 
69
+ /**
70
+ * Process lock for setting a bucket
71
+ */
72
+ bucketSelectLock: false,
73
 
74
+ /**
75
+ * Load bucket list
76
+ *
77
+ * @param {bool} [forceUpdate]
78
+ */
79
+ loadList: function( forceUpdate ) {
80
+ if ( 'undefined' === typeof forceUpdate ) {
81
+ forceUpdate = false;
82
+ }
83
 
84
+ var $bucketList = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-bucket-list' );
85
+ var selectedBucket = $( '#' + as3cfModal.prefix + '-bucket' ).val();
 
 
 
 
 
 
 
 
 
86
 
87
+ if ( false === forceUpdate && $bucketList.find( 'li' ).length > 1 ) {
88
+ $( '.as3cf-bucket-list a' ).removeClass( 'selected' );
89
+ $( '.as3cf-bucket-list a[data-bucket="' + selectedBucket + '"]' ).addClass( 'selected' );
90
 
91
+ this.scrollToSelected();
92
+ return;
93
+ }
 
94
 
95
+ $bucketList.html( '<li class="loading">' + $bucketList.attr( 'data-working' ) + '</li>' );
96
+
97
+ var data = {
98
+ action: as3cfModal.prefix + '-get-buckets',
99
+ _nonce: window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.get_buckets
100
+ };
101
+
102
+ var that = this;
103
+
104
+ $.ajax( {
105
+ url : ajaxurl,
106
+ type : 'POST',
107
+ dataType: 'JSON',
108
+ data : data,
109
+ error : function( jqXHR, textStatus, errorThrown ) {
110
+ $bucketList.html( '' );
111
+ that.showError( as3cf.strings.get_buckets_error, errorThrown, 'as3cf-bucket-select' );
112
+ },
113
+ success : function( data, textStatus, jqXHR ) {
114
+ $bucketList.html( '' );
115
+
116
+ if ( typeof data[ 'success' ] !== 'undefined' ) {
117
+ $( '.as3cf-bucket-error' ).hide();
118
+
119
+ $( data[ 'buckets' ] ).each( function( idx, bucket ) {
120
+ var bucketClass = bucket.Name === selectedBucket ? 'selected' : '';
121
+ $bucketList.append( '<li><a class="' + bucketClass + '" href="#" data-bucket="' + bucket.Name + '"><span class="bucket"><span class="dashicons dashicons-portfolio"></span> ' + bucket.Name + '</span><span class="spinner"></span></span></a></li>' );
122
+ } );
123
+
124
+ that.scrollToSelected();
125
+ } else {
126
+ that.showError( as3cf.strings.get_buckets_error, data[ 'error' ], 'as3cf-bucket-select' );
127
+ }
128
  }
129
+ } );
130
+ },
131
+
132
+ /**
133
+ * Scroll to selected bucket
134
+ */
135
+ scrollToSelected: function() {
136
+ if ( ! $( '.as3cf-bucket-list a.selected' ).length ) {
137
+ return;
138
  }
 
 
139
 
140
+ var offset = $( 'ul.as3cf-bucket-list li' ).first().position().top + 150;
 
 
 
 
 
 
141
 
142
+ $( '.as3cf-bucket-list' ).animate( {
143
+ scrollTop: $( 'ul.as3cf-bucket-list li a.selected' ).position().top - offset
144
+ } );
145
+ },
146
 
147
+ /**
148
+ * Reset bucket modal
149
+ */
150
+ resetModal: function() {
151
+ var $bucketContainer = $( '.as3cf-bucket-container.' + as3cfModal.prefix );
152
 
153
+ if ( false === $activeTab.hasClass( 'as3cf-has-bucket' ) || 'manual' === $( '#' + as3cfModal.prefix + '-bucket-select' ).val() ) {
154
+ $bucketContainer.find( '.as3cf-bucket-manual' ).show().siblings().hide();
155
+ $bucketContainer.find( '.bucket-actions.manual' ).show().siblings( '.bucket-actions' ).hide();
156
+ } else {
157
+ $bucketContainer.find( '.as3cf-bucket-select' ).show().siblings().hide();
158
+ $bucketContainer.find( '.bucket-actions.select' ).show().siblings( '.bucket-actions' ).hide();
159
 
160
+ this.loadList();
161
+ }
 
 
 
 
162
 
163
+ $bucketContainer.find( '.as3cf-bucket-error' ).hide();
 
164
 
165
+ // Reset manual select value
166
+ var bucket = $( '#' + as3cfModal.prefix + '-bucket' ).val();
167
+ $bucketContainer.find( '.as3cf-bucket-manual .as3cf-bucket-name' ).val( bucket );
168
 
169
+ // Unlock setting the bucket
170
+ this.bucketSelectLock = false;
171
+ },
 
172
 
173
+ /**
174
+ * Save manual bucket
175
+ */
176
+ saveManual: function() {
177
+ var $manualBucketForm = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-manual-save-bucket-form' );
178
+ var $manualBucketInput = $manualBucketForm.find( '.as3cf-bucket-name' );
179
+ var $manualBucketButton = $manualBucketForm.find( 'button[type=submit]' );
180
+ var bucketName = $manualBucketInput.val();
181
+ var originalBucketText = $manualBucketButton.first().text();
182
+
183
+ if ( bucketName === $( '#' + as3cfModal.prefix + '-active-bucket' ).text() ) {
184
+ $( '.as3cf-bucket-error' ).hide();
185
+ $activeTab.addClass( 'as3cf-has-bucket' );
186
+ as3cfModal.close();
187
+ return;
188
+ }
189
  $( '.as3cf-bucket-error' ).hide();
190
+ $manualBucketButton.text( $manualBucketButton.attr( 'data-working' ) );
191
+ $manualBucketButton.prop( 'disabled', true );
192
+
193
+ var data = {
194
+ action : as3cfModal.prefix + '-manual-save-bucket',
195
+ bucket_name: bucketName,
196
+ _nonce : window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.manual_bucket
197
+ };
198
+
199
+ var that = this;
200
+
201
+ $.ajax( {
202
+ url : ajaxurl,
203
+ type : 'POST',
204
+ dataType: 'JSON',
205
+ data : data,
206
+ error : function( jqXHR, textStatus, errorThrown ) {
207
+ $manualBucketButton.text( originalBucketText );
208
+ that.showError( as3cf.strings.save_bucket_error, errorThrown, 'as3cf-bucket-manual' );
209
+ },
210
+ success : function( data, textStatus, jqXHR ) {
211
+ $manualBucketButton.text( originalBucketText );
212
+ $manualBucketButton.prop( 'disabled', false );
213
+ if ( typeof data[ 'success' ] !== 'undefined' ) {
214
+ that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
215
+ $( '#' + as3cfModal.prefix + '-bucket-select' ).val( 'manual' );
216
+ $( '.as3cf-bucket-list a' ).removeClass( 'selected' ).filter( '[data-bucket="' + bucketName + '"]' ).addClass( 'selected' );
217
+ } else {
218
+ that.showError( as3cf.strings.save_bucket_error, data[ 'error' ], 'as3cf-bucket-manual' );
219
+ }
220
+ }
221
+ } );
222
+ },
223
 
224
+ /**
225
+ * Save select bucket
226
+ *
227
+ * @param {object} $link
228
+ */
229
+ saveSelected: function( $link ) {
230
+ var $bucketList = $( '.as3cf-bucket-list' );
231
 
232
+ if ( this.bucketSelectLock ) {
233
+ // Bail if a bucket has already been clicked
234
+ return;
235
+ }
236
+
237
+ // Lock the bucket selection
238
+ this.bucketSelectLock = true;
239
+
240
+ if ( $link.hasClass( 'selected' ) ) {
241
+ $activeTab.addClass( 'as3cf-has-bucket' );
242
+ as3cfModal.close();
243
+ return;
244
+ }
245
+
246
+ var previousBucket = $( '.as3cf-bucket-list a.selected' ).attr( 'data-bucket' );
247
+
248
+ $( '.as3cf-bucket-list a' ).removeClass( 'selected' );
249
+ $link.addClass( 'selected' );
250
+
251
+ $bucketList.addClass( 'saving' );
252
+ $link.find( '.spinner' ).show().css( 'visibility', 'visible' );
253
+ var bucketName = $link.attr( 'data-bucket' );
254
+
255
+ var data = {
256
+ action : as3cfModal.prefix + '-save-bucket',
257
+ bucket_name: bucketName,
258
+ _nonce : window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.save_bucket
259
+ };
260
+
261
+ var that = this;
262
+
263
+ $.ajax( {
264
+ url : ajaxurl,
265
+ type : 'POST',
266
+ dataType: 'JSON',
267
+ data : data,
268
+ error : function( jqXHR, textStatus, errorThrown ) {
269
+ $bucketList.removeClass( 'saving' );
270
+ that.showError( as3cf.strings.save_bucket_error, errorThrown, 'as3cf-bucket-select' );
271
+ $( '.as3cf-bucket-list a' ).removeClass( 'selected' );
272
+ $( '.as3cf-bucket-list a[data-bucket="' + previousBucket + '"]' ).addClass( 'selected' );
273
+ },
274
+ success : function( data, textStatus, jqXHR ) {
275
+ $link.find( '.spinner' ).hide().css( 'visibility', 'hidden' );
276
+ $bucketList.removeClass( 'saving' );
277
+ if ( typeof data[ 'success' ] !== 'undefined' ) {
278
+ that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
279
+ $( '#' + as3cfModal.prefix + '-bucket-select' ).val( '' );
280
+ } else {
281
+ that.showError( as3cf.strings.save_bucket_error, data[ 'error' ], 'as3cf-bucket-select' );
282
+ $( '.as3cf-bucket-list a' ).removeClass( 'selected' );
283
+ $( '.as3cf-bucket-list a[data-bucket="' + previousBucket + '"]' ).addClass( 'selected' );
284
+ }
285
  }
286
+ } );
287
+ },
288
+
289
+ /**
290
+ * Disable bucket buttons
291
+ */
292
+ disabledButtons: function() {
293
+ if ( 0 === $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-create-bucket-form' ).length ) {
294
+ return;
295
  }
 
 
296
 
297
+ var $createBucketForm = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-create-bucket-form' );
298
+ var $manualBucketForm = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-manual-save-bucket-form' );
 
 
 
 
 
299
 
300
+ if ( $createBucketForm.find( '.as3cf-bucket-name' ).val().length < 3 ) {
301
+ $createBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
302
+ }
303
+ else {
304
+ $createBucketForm.find( 'button[type=submit]' ).attr( 'disabled', false );
305
+ }
306
 
307
+ if ( $manualBucketForm.find( '.as3cf-bucket-name' ).val().length < 3 ) {
308
+ $manualBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
309
+ }
310
+ else {
311
+ $manualBucketForm.find( 'button[type=submit]' ).attr( 'disabled', false );
312
+ }
313
+ },
314
 
315
+ /**
316
+ * Show bucket error
317
+ *
318
+ * @param {string} title
319
+ * @param {string} error
320
+ * @param {string} [context]
321
+ */
322
+ showError: function( title, error, context ) {
323
+ var $activeView = $( '.as3cf-bucket-container' ).children( ':visible' );
324
+ var $bucketError = $activeView.find( '.as3cf-bucket-error' );
325
 
326
+ context = ('undefined' === typeof context) ? null : context;
 
 
327
 
328
+ if ( context && ! $activeView.hasClass( context ) ) {
329
+ return;
330
+ }
 
 
331
 
332
+ $bucketError.find( 'span.title' ).html( title + ' &mdash;' );
333
+ $bucketError.find( 'span.message' ).html( error );
334
+ $bucketError.show();
335
+
336
+ // Unlock setting the bucket
337
+ this.bucketSelectLock = false;
338
+ },
339
+
340
+ /**
341
+ * Set the selected bucket in the UI
342
+ *
343
+ * @param {string} bucket
344
+ * @param {string} region
345
+ * @param {bool} canWrite
346
+ */
347
+ set: function( bucket, region, canWrite ) {
348
+ var $manualBucketForm = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-manual-save-bucket-form' );
349
+ var $activeBucket = $( '#' + as3cfModal.prefix + '-active-bucket' );
350
+
351
+ if ( 'as3cf' === as3cfModal.prefix && '' === $activeBucket.text() ) {
352
+ // first time bucket select - enable main options by default
353
+ setCheckbox( 'copy-to-s3-wrap' );
354
+ setCheckbox( 'serve-from-s3-wrap' );
355
+
356
+ // update the saved settings string so we don't trigger the navigation alert
357
+ var id = $activeTab.attr( 'id' );
358
+ savedSettings[ id ] = serializedForm( id );
359
  }
 
 
360
 
361
+ $activeBucket.text( bucket );
362
+ $manualBucketForm.find( '.as3cf-bucket-name' ).val( bucket );
363
+ $( '#' + as3cfModal.prefix + '-bucket' ).val( bucket );
364
+ $( '#' + as3cfModal.prefix + '-region' ).val( region );
365
+ $( '.updated' ).not( '.as3cf-notice' ).show();
 
 
366
 
367
+ $activeTab.addClass( 'as3cf-has-bucket' );
368
+ // check permission on bucket
369
+ $activeTab.find( '.as3cf-can-write-error' ).toggle( ! canWrite );
370
+ $activeTab.find( '.as3cf-bucket-error' ).hide();
371
 
372
+ if ( 'as3cf' === as3cfModal.prefix ) {
373
+ generateUrlPreview();
374
+ }
 
 
 
375
 
376
+ as3cfModal.close( unlockBucketSelect );
377
+ },
 
 
 
 
 
378
 
379
+ /**
380
+ * Save create bucket
381
+ */
382
+ create: function() {
383
+ var $createBucketForm = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-create-bucket-form' );
384
+ var $createBucketInput = $createBucketForm.find( '.as3cf-bucket-name' );
385
+ var $createBucketSelect = $createBucketForm.find( '.bucket-create-region' );
386
+ var $createBucketButton = $createBucketForm.find( 'button[type=submit]' );
 
 
387
 
388
+ var bucketName = $createBucketInput.val();
389
+ var origButtonText = $createBucketButton.text();
390
 
391
+ $( '.as3cf-bucket-error' ).hide();
392
+ $createBucketButton.text( $createBucketButton.attr( 'data-working' ) );
393
+ $createBucketButton.prop( 'disabled', true );
394
 
395
+ var data = {
396
+ action : as3cfModal.prefix + '-create-bucket',
397
+ bucket_name: bucketName,
398
+ _nonce : window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.create_bucket
399
+ };
400
 
401
+ if ( $createBucketSelect.val() ) {
402
+ data[ 'region' ] = $createBucketSelect.val();
403
+ }
404
+
405
+ var that = this;
406
+
407
+ $.ajax( {
408
+ url : ajaxurl,
409
+ type : 'POST',
410
+ dataType: 'JSON',
411
+ data : data,
412
+ error : function( jqXHR, textStatus, errorThrown ) {
413
+ $createBucketButton.text( origButtonText );
414
+ that.showError( as3cf.strings.create_bucket_error, errorThrown, 'as3cf-bucket-create' );
415
+ },
416
+ success : function( data, textStatus, jqXHR ) {
417
+ $createBucketButton.text( origButtonText );
418
+ $createBucketButton.prop( 'disabled', false );
419
+ if ( typeof data[ 'success' ] !== 'undefined' ) {
420
+ that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
421
+ // tidy up create bucket form
422
+ $( '.as3cf-bucket-select-region' ).hide();
423
+ $( '.as3cf-bucket-select-region' ).removeAttr( 'selected' );
424
+ $createBucketInput.val( '' );
425
+ $createBucketButton.attr( 'disabled', true );
426
+ } else {
427
+ that.showError( as3cf.strings.create_bucket_error, data[ 'error' ], 'as3cf-bucket-create' );
428
+ }
429
+ }
430
+ } );
431
+ },
432
 
433
+ /**
434
+ * Check for a valid bucket name
435
+ *
436
+ * Bucket names must be at least 3 and no more than 63 characters long.
437
+ * They can contain lowercase letters, numbers, periods and hyphens.
438
+ *
439
+ * @param {string} bucketName
440
+ *
441
+ * @return bool
442
+ */
443
+ isValidName: function( bucketName ) {
444
+ if ( bucketName.length < 3 || bucketName.length > 63 ) {
445
+ return false;
446
+ }
447
+ if ( true === bucketNamePattern.test( bucketName ) ) {
448
+ return false;
449
+ }
450
 
451
+ return true;
452
+ },
 
 
453
 
454
+ /**
455
+ * Update invalid bucket name notice
456
+ *
457
+ * @param {string} bucketName
458
+ */
459
+ updateNameNotice: function( bucketName ) {
460
+ var message = null;
461
+
462
+ if ( true === bucketNamePattern.test( bucketName ) ) {
463
+ message = as3cf.strings.create_bucket_invalid_chars;
464
+ } else if ( bucketName.length < 3 ) {
465
+ message = as3cf.strings.create_bucket_name_short;
466
+ } else if ( bucketName.length > 63 ) {
467
+ message = as3cf.strings.create_bucket_name_long;
468
+ }
469
+
470
+ if ( message && bucketName.length > 0 ) {
471
+ $( '.as3cf-invalid-bucket-name' ).html( message );
472
+ } else {
473
+ $( '.as3cf-invalid-bucket-name' ).html( '' );
474
+ }
475
  }
476
 
477
+ };
 
478
 
479
  /**
480
  * Generate URL preview
486
  _nonce: as3cf.nonces.get_url_preview
487
  };
488
 
489
+ $.each( $( '#tab-' + as3cf.tabs.defaultTab + ' .as3cf-main-settings form' ).serializeArray(), function( i, o ) {
490
  var n = o.name,
491
  v = o.value;
492
  n = n.replace( '[]', '' );
515
  }
516
 
517
  /**
518
+ * Reset the bucket select lock
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
519
  */
520
+ function unlockBucketSelect( target ) {
521
+ // Unlock setting the bucket
522
+ as3cf.buckets.bucketSelectLock = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
523
  }
524
 
525
  $( document ).ready( function() {
537
  as3cf.tabs.toggle( hash, true );
538
  } else {
539
  // default settings tab
540
+ $activeTab = $( '#tab-' + as3cf.tabs.defaultTab );
541
+ $( '.aws-main' ).attr( 'data-tab', as3cf.tabs.defaultTab );
 
542
  }
543
 
544
  $( '.aws-main' ).on( 'click', '.nav-tab', function( e ) {
641
  $( 'body' ).on( 'click', '.bucket-action-browse', function( e ) {
642
  e.preventDefault();
643
  $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-bucket-select' ).show().siblings().hide();
644
+ as3cf.buckets.loadList();
 
645
  } );
646
  $( 'body' ).on( 'click', '.bucket-action-create', function( e ) {
647
  e.preventDefault();
654
  } );
655
  $( 'body' ).on( 'click', '.bucket-action-cancel', function( e ) {
656
  e.preventDefault();
657
+ as3cf.buckets.resetModal();
658
  } );
659
  $( 'body' ).on( 'click', '.bucket-action-save', function( e ) {
660
  e.preventDefault();
661
+ as3cf.buckets.saveManual();
662
  } );
663
  $( 'body' ).on( 'click', '.as3cf-create-bucket-form button[type="submit"]', function( e ) {
664
  e.preventDefault();
665
+ as3cf.buckets.create();
666
  } );
667
 
668
  // Bucket list refresh handler
669
  $( 'body' ).on( 'click', '.bucket-action-refresh', function( e ) {
670
  e.preventDefault();
671
+ as3cf.buckets.loadList( true );
672
  } );
673
 
674
  // Bucket list click handler
675
  $( 'body' ).on( 'click', '.as3cf-bucket-list a', function( e ) {
676
  e.preventDefault();
677
+ as3cf.buckets.saveSelected( $( this ) );
678
+ } );
679
+
680
+ // External links click handler
681
+ $( '.as3cf-bucket-container' ).on( 'click', 'a.js-link', function( e ) {
682
+ e.preventDefault();
683
+ window.open( $( this ).attr( 'href' ) );
684
+
685
+ return false;
686
  } );
687
 
688
  // Modal open
689
  $( 'body' ).on( 'as3cf-modal-open', function( e, target ) {
690
  if ( '.as3cf-bucket-container.' + as3cfModal.prefix === target ) {
691
  // Reset modal
692
+ as3cf.buckets.resetModal();
693
  // Change manual title text
694
  var title = $( '.as3cf-bucket-manual h3' ).data( 'modal-title' );
695
  $( '.as3cf-bucket-manual h3' ).text( title );
696
  // Hide buttons
697
+ as3cf.buckets.disabledButtons();
698
  }
699
  } );
700
+
701
+ as3cf.buckets.disabledButtons();
702
 
703
  // Validate bucket name on create
704
  $( 'body' ).on( 'input keyup', '.as3cf-create-bucket-form .as3cf-bucket-name', function( e ) {
705
  var bucketName = $( this ).val();
706
  var $createBucketForm = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-create-bucket-form' );
707
 
708
+ if ( as3cf.buckets.isValidName( bucketName ) ) {
709
  $createBucketForm.find( 'button[type=submit]' ).removeAttr( 'disabled' );
710
  } else {
711
  $createBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
712
  }
713
+ as3cf.buckets.updateNameNotice( bucketName );
714
  } );
715
 
716
  // Check bucket name length on manual
717
  $( 'body' ).on( 'input keyup', '.as3cf-manual-save-bucket-form .as3cf-bucket-name', function( e ) {
718
  var $manualBucketForm = $( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-manual-save-bucket-form' );
719
 
720
+ if ( $manualBucketForm.find( '.as3cf-bucket-name' ).val().length < as3cf.buckets.validLength ) {
721
  $manualBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
722
  } else {
723
  $manualBucketForm.find( 'button[type=submit]' ).removeAttr( 'disabled' );
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(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 f();d.html('<li class="loading">'+d.attr("data-working")+"</li>");var g={action:b.prefix+"-get-buckets",_nonce:window[b.prefix.replace(/-/g,"_")].nonces.get_buckets};a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:g,error:function(a,b,c){d.html(""),k(as3cf.strings.get_buckets_error,c,"as3cf-bucket-select")},success:function(b){d.html(""),"undefined"!=typeof b.success?(a(".as3cf-bucket-error").hide(),a(b.buckets).each(function(a,b){var c=b.Name===e?"selected":"";d.append('<li><a class="'+c+'" href="#" data-bucket="'+b.Name+'"><span class="bucket"><span class="dashicons dashicons-portfolio"></span> '+b.Name+'</span><span class="spinner"></span></span></a></li>')}),f()):k(as3cf.strings.get_buckets_error,b.error,"as3cf-bucket-select")}})}function f(){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})}}function g(){var c=a(".as3cf-bucket-container."+b.prefix);!1===q.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(),e()),c.find(".as3cf-bucket-error").hide();var d=a("#"+b.prefix+"-bucket").val();c.find(".as3cf-bucket-manual .as3cf-bucket-name").val(d)}function h(){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(),q.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};a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:h,error:function(a,b,c){e.text(g),k(as3cf.strings.save_bucket_error,c,"as3cf-bucket-manual")},success:function(c){e.text(g),e.prop("disabled",!1),"undefined"!=typeof c.success?(l(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")):k(as3cf.strings.save_bucket_error,c.error,"as3cf-bucket-manual")}})}function i(c){var d=a(".as3cf-bucket-list");if(c.hasClass("selected"))return q.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};a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:g,error:function(b,c,f){d.removeClass("saving"),k(as3cf.strings.save_bucket_error,f,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected")},success:function(g){c.find(".spinner").hide().css("visibility","hidden"),d.removeClass("saving"),"undefined"!=typeof g.success?(l(f,g.region,g.can_write),a("#"+b.prefix+"-bucket-select").val("")):(k(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"))}})}function j(){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)}}function k(b,c,d){var e=a(".as3cf-bucket-container").children(":visible"),f=e.find(".as3cf-bucket-error");d="undefined"==typeof d?null:d,(!d||e.hasClass(d))&&(f.find("span.title").html(b),f.find("span.message").html(c),f.show())}function l(c,e,f){var g=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),h=a("#"+b.prefix+"-active-bucket");"as3cf"===b.prefix&&""===h.text()&&(d("copy-to-s3-wrap"),d("serve-from-s3-wrap")),h.text(c),g.find(".as3cf-bucket-name").val(c),a("#"+b.prefix+"-bucket").val(c),a("#"+b.prefix+"-region").val(e),a(".updated").not(".as3cf-notice").show(),q.addClass("as3cf-has-bucket"),q.find(".as3cf-can-write-error").toggle(!f),q.find(".as3cf-bucket-error").hide(),"as3cf"===b.prefix&&m(),b.close()}function m(){a(".as3cf-url-preview").html("Generating...");var b={_nonce:as3cf.nonces.get_url_preview};a.each(a("#tab-media .as3cf-main-settings form").serializeArray(),function(c,d){var e=d.name,f=d.value;e=e.replace("[]",""),b[e]=void 0===b[e]?f:a.isArray(b[e])?b[e].concat(f):[b[e],f]}),b.action="as3cf-get-url-preview",a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:b,error:function(a,b,c){alert(as3cf.strings.get_url_preview_error+c)},success:function(b){"undefined"!=typeof b.success?a(".as3cf-url-preview").html(b.url):alert(as3cf.strings.get_url_preview_error+b.error)}})}function n(a){return a.length<3||a.length>63?!1:!0===s.test(a)?!1:!0}function o(b){var c=null;!0===s.test(b)?c=as3cf.strings.create_bucket_invalid_chars:b.length<3?c=as3cf.strings.create_bucket_name_short:b.length>63&&(c=as3cf.strings.create_bucket_name_long),a(".as3cf-invalid-bucket-name").html(c&&b.length>0?c:"")}function p(){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()),a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:i,error:function(a,b,c){f.text(h),k(as3cf.strings.create_bucket_error,c,"as3cf-bucket-create")},success:function(b){f.text(h),f.prop("disabled",!1),"undefined"!=typeof b.success?(l(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)):k(as3cf.strings.create_bucket_error,b.error,"as3cf-bucket-create")}})}var q,r={},s=/[^a-z0-9.-]/,t=a(".as3cf-tab");as3cf.tabs={toggle:function(c,d){t.hide(),q=a("#tab-"+c),q.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),q.attr("data-prefix")&&(b.prefix=q.attr("data-prefix")),d||a(".as3cf-updated").removeClass("show")}},a(document).ready(function(){var f=a(".wrap.aws-main .nav-tab-wrapper");if(a(".aws-compatibility-notice, div.updated, div.error, div.notice").not(".below-h2, .inline").insertAfter(f),window.location.hash){var k=window.location.hash.substring(1);as3cf.tabs.toggle(k,!0)}else{var l="media";q=a("#tab-"+l),a(".aws-main").attr("data-tab",l)}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}}),t.length&&t.each(function(a,b){r[b.id]=c(b.id)}),a(window).on("beforeunload.as3cf-settings",function(){if(!a.isEmptyObject(r)){var b=q.attr("id");return c(b)!==r[b]?as3cf.strings.save_alert:void 0}}),a(document).on("submit",".as3cf-main-settings form",function(){a(window).off("beforeunload.as3cf-settings")}),a(".as3cf-switch").on("click",function(){a(this).hasClass("disabled")||d(a(this).attr("id"))}),t.on("change",".sub-toggle",function(){var b=a(this).attr("id");a(".as3cf-setting."+b).toggleClass("hide")}),a(".as3cf-domain").on("change",'input[type="radio"]',function(){var b=a(this).closest('input:radio[name="domain"]:checked'),c=b.val(),d=a(this).parents(".as3cf-domain").find(".as3cf-setting.cloudfront"),e="cloudfront"===c;d.toggleClass("hide",!e)}),a(".as3cf-ssl").on("change",'input[type="radio"]',function(){var b=a('input:radio[name="ssl"]:checked').val();if("https"===b){var c=a('input:radio[name="domain"]:checked').val();"subdomain"===c&&a('input[name="domain"][value="path"]').attr("checked",!0),a(".subdomain-wrap input").attr("disabled",!0),a(".subdomain-wrap").addClass("disabled")}else a(".subdomain-wrap input").removeAttr("disabled"),a(".subdomain-wrap").removeClass("disabled")}),a(".url-preview").on("change","input",function(){m()}),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(),e()}),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(),g()}),a("body").on("click",".bucket-action-save",function(a){a.preventDefault(),h()}),a("body").on("click",'.as3cf-create-bucket-form button[type="submit"]',function(a){a.preventDefault(),p()}),a("body").on("click",".bucket-action-refresh",function(a){a.preventDefault(),e(!0)}),a("body").on("click",".as3cf-bucket-list a",function(b){b.preventDefault(),i(a(this))}),a("body").on("as3cf-modal-open",function(c,d){if(".as3cf-bucket-container."+b.prefix===d){g();var e=a(".as3cf-bucket-manual h3").data("modal-title");a(".as3cf-bucket-manual h3").text(e),j()}}),j(),a("body").on("input keyup",".as3cf-create-bucket-form .as3cf-bucket-name",function(){var c=a(this).val(),d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form");n(c)?d.find("button[type=submit]").removeAttr("disabled"):d.find("button[type=submit]").attr("disabled",!0),o(c)}),a("body").on("input keyup",".as3cf-manual-save-bucket-form .as3cf-bucket-name",function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");c.find(".as3cf-bucket-name").val().length<3?c.find("button[type=submit]").attr("disabled",!0):c.find("button[type=submit]").removeAttr("disabled")})})}(jQuery,as3cfModal);
1
+ !function(a,b){function c(b){return a("#"+b+" .as3cf-main-settings form").find("input:not(.no-compare)").serialize()}function d(b){var c=a("#"+b),d=c.find("input[type=checkbox]");c.toggleClass("on").find("span").toggleClass("checked");var e=c.find("span.on").hasClass("checked");d.attr("checked",e).trigger("change")}function e(){a(".as3cf-url-preview").html("Generating...");var b={_nonce:as3cf.nonces.get_url_preview};a.each(a("#tab-"+as3cf.tabs.defaultTab+" .as3cf-main-settings form").serializeArray(),function(c,d){var e=d.name,f=d.value;e=e.replace("[]",""),b[e]=void 0===b[e]?f:a.isArray(b[e])?b[e].concat(f):[b[e],f]}),b.action="as3cf-get-url-preview",a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:b,error:function(a,b,c){alert(as3cf.strings.get_url_preview_error+c)},success:function(b){"undefined"!=typeof b.success?a(".as3cf-url-preview").html(b.url):alert(as3cf.strings.get_url_preview_error+b.error)}})}function f(){as3cf.buckets.bucketSelectLock=!1}var g,h={},i=/[^a-z0-9.-]/,j=a(".as3cf-tab");as3cf.tabs={defaultTab:"media",toggle:function(c,d){j.hide(),g=a("#tab-"+c),g.show(),a(".nav-tab").removeClass("nav-tab-active"),a('a.nav-tab[data-tab="'+c+'"]').addClass("nav-tab-active"),a(".aws-main").attr("data-tab",c),g.attr("data-prefix")&&(b.prefix=g.attr("data-prefix")),d||a(".as3cf-updated").removeClass("show")}},as3cf.buckets={validLength:3,bucketSelectLock:!1,loadList:function(c){"undefined"==typeof c&&(c=!1);var d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-list"),e=a("#"+b.prefix+"-bucket").val();if(!1===c&&d.find("li").length>1)return a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected"),void this.scrollToSelected();d.html('<li class="loading">'+d.attr("data-working")+"</li>");var f={action:b.prefix+"-get-buckets",_nonce:window[b.prefix.replace(/-/g,"_")].nonces.get_buckets},g=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:f,error:function(a,b,c){d.html(""),g.showError(as3cf.strings.get_buckets_error,c,"as3cf-bucket-select")},success:function(b){d.html(""),"undefined"!=typeof b.success?(a(".as3cf-bucket-error").hide(),a(b.buckets).each(function(a,b){var c=b.Name===e?"selected":"";d.append('<li><a class="'+c+'" href="#" data-bucket="'+b.Name+'"><span class="bucket"><span class="dashicons dashicons-portfolio"></span> '+b.Name+'</span><span class="spinner"></span></span></a></li>')}),g.scrollToSelected()):g.showError(as3cf.strings.get_buckets_error,b.error,"as3cf-bucket-select")}})},scrollToSelected:function(){if(a(".as3cf-bucket-list a.selected").length){var b=a("ul.as3cf-bucket-list li").first().position().top+150;a(".as3cf-bucket-list").animate({scrollTop:a("ul.as3cf-bucket-list li a.selected").position().top-b})}},resetModal:function(){var c=a(".as3cf-bucket-container."+b.prefix);!1===g.hasClass("as3cf-has-bucket")||"manual"===a("#"+b.prefix+"-bucket-select").val()?(c.find(".as3cf-bucket-manual").show().siblings().hide(),c.find(".bucket-actions.manual").show().siblings(".bucket-actions").hide()):(c.find(".as3cf-bucket-select").show().siblings().hide(),c.find(".bucket-actions.select").show().siblings(".bucket-actions").hide(),this.loadList()),c.find(".as3cf-bucket-error").hide();var d=a("#"+b.prefix+"-bucket").val();c.find(".as3cf-bucket-manual .as3cf-bucket-name").val(d),this.bucketSelectLock=!1},saveManual:function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),d=c.find(".as3cf-bucket-name"),e=c.find("button[type=submit]"),f=d.val(),h=e.first().text();if(f===a("#"+b.prefix+"-active-bucket").text())return a(".as3cf-bucket-error").hide(),g.addClass("as3cf-has-bucket"),void b.close();a(".as3cf-bucket-error").hide(),e.text(e.attr("data-working")),e.prop("disabled",!0);var i={action:b.prefix+"-manual-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.manual_bucket},j=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:i,error:function(a,b,c){e.text(h),j.showError(as3cf.strings.save_bucket_error,c,"as3cf-bucket-manual")},success:function(c){e.text(h),e.prop("disabled",!1),"undefined"!=typeof c.success?(j.set(f,c.region,c.can_write),a("#"+b.prefix+"-bucket-select").val("manual"),a(".as3cf-bucket-list a").removeClass("selected").filter('[data-bucket="'+f+'"]').addClass("selected")):j.showError(as3cf.strings.save_bucket_error,c.error,"as3cf-bucket-manual")}})},saveSelected:function(c){var d=a(".as3cf-bucket-list");if(!this.bucketSelectLock){if(this.bucketSelectLock=!0,c.hasClass("selected"))return g.addClass("as3cf-has-bucket"),void b.close();var e=a(".as3cf-bucket-list a.selected").attr("data-bucket");a(".as3cf-bucket-list a").removeClass("selected"),c.addClass("selected"),d.addClass("saving"),c.find(".spinner").show().css("visibility","visible");var f=c.attr("data-bucket"),h={action:b.prefix+"-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.save_bucket},i=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:h,error:function(b,c,f){d.removeClass("saving"),i.showError(as3cf.strings.save_bucket_error,f,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected")},success:function(g){c.find(".spinner").hide().css("visibility","hidden"),d.removeClass("saving"),"undefined"!=typeof g.success?(i.set(f,g.region,g.can_write),a("#"+b.prefix+"-bucket-select").val("")):(i.showError(as3cf.strings.save_bucket_error,g.error,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected"))}})}},disabledButtons:function(){if(0!==a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form").length){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form"),d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");c.find(".as3cf-bucket-name").val().length<3?c.find("button[type=submit]").attr("disabled",!0):c.find("button[type=submit]").attr("disabled",!1),d.find(".as3cf-bucket-name").val().length<3?d.find("button[type=submit]").attr("disabled",!0):d.find("button[type=submit]").attr("disabled",!1)}},showError:function(b,c,d){var e=a(".as3cf-bucket-container").children(":visible"),f=e.find(".as3cf-bucket-error");d="undefined"==typeof d?null:d,(!d||e.hasClass(d))&&(f.find("span.title").html(b+" &mdash;"),f.find("span.message").html(c),f.show(),this.bucketSelectLock=!1)},set:function(i,j,k){var l=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),m=a("#"+b.prefix+"-active-bucket");if("as3cf"===b.prefix&&""===m.text()){d("copy-to-s3-wrap"),d("serve-from-s3-wrap");var n=g.attr("id");h[n]=c(n)}m.text(i),l.find(".as3cf-bucket-name").val(i),a("#"+b.prefix+"-bucket").val(i),a("#"+b.prefix+"-region").val(j),a(".updated").not(".as3cf-notice").show(),g.addClass("as3cf-has-bucket"),g.find(".as3cf-can-write-error").toggle(!k),g.find(".as3cf-bucket-error").hide(),"as3cf"===b.prefix&&e(),b.close(f)},create:function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form"),d=c.find(".as3cf-bucket-name"),e=c.find(".bucket-create-region"),f=c.find("button[type=submit]"),g=d.val(),h=f.text();a(".as3cf-bucket-error").hide(),f.text(f.attr("data-working")),f.prop("disabled",!0);var i={action:b.prefix+"-create-bucket",bucket_name:g,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.create_bucket};e.val()&&(i.region=e.val());var j=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:i,error:function(a,b,c){f.text(h),j.showError(as3cf.strings.create_bucket_error,c,"as3cf-bucket-create")},success:function(b){f.text(h),f.prop("disabled",!1),"undefined"!=typeof b.success?(j.set(g,b.region,b.can_write),a(".as3cf-bucket-select-region").hide(),a(".as3cf-bucket-select-region").removeAttr("selected"),d.val(""),f.attr("disabled",!0)):j.showError(as3cf.strings.create_bucket_error,b.error,"as3cf-bucket-create")}})},isValidName:function(a){return a.length<3||a.length>63?!1:!0===i.test(a)?!1:!0},updateNameNotice:function(b){var c=null;!0===i.test(b)?c=as3cf.strings.create_bucket_invalid_chars:b.length<3?c=as3cf.strings.create_bucket_name_short:b.length>63&&(c=as3cf.strings.create_bucket_name_long),a(".as3cf-invalid-bucket-name").html(c&&b.length>0?c:"")}},a(document).ready(function(){var f=a(".wrap.aws-main .nav-tab-wrapper");if(a(".aws-compatibility-notice, div.updated, div.error, div.notice").not(".below-h2, .inline").insertAfter(f),window.location.hash){var i=window.location.hash.substring(1);as3cf.tabs.toggle(i,!0)}else g=a("#tab-"+as3cf.tabs.defaultTab),a(".aws-main").attr("data-tab",as3cf.tabs.defaultTab);a(".aws-main").on("click",".nav-tab",function(b){if(b.preventDefault(),!a(this).hasClass("nav-tab-active")){var c=a(this).attr("data-tab");as3cf.tabs.toggle(c),"media"===c?(window.location.hash="","function"==typeof window.history.replaceState&&"#"===window.location.href.slice(-1)&&history.replaceState({},"",window.location.href.slice(0,-1))):window.location.hash=c}}),j.length&&j.each(function(a,b){h[b.id]=c(b.id)}),a(window).on("beforeunload.as3cf-settings",function(){if(!a.isEmptyObject(h)){var b=g.attr("id");return c(b)!==h[b]?as3cf.strings.save_alert:void 0}}),a(document).on("submit",".as3cf-main-settings form",function(){a(window).off("beforeunload.as3cf-settings")}),a(".as3cf-switch").on("click",function(){a(this).hasClass("disabled")||d(a(this).attr("id"))}),j.on("change",".sub-toggle",function(){var b=a(this).attr("id");a(".as3cf-setting."+b).toggleClass("hide")}),a(".as3cf-domain").on("change",'input[type="radio"]',function(){var b=a(this).closest('input:radio[name="domain"]:checked'),c=b.val(),d=a(this).parents(".as3cf-domain").find(".as3cf-setting.cloudfront"),e="cloudfront"===c;d.toggleClass("hide",!e)}),a(".as3cf-ssl").on("change",'input[type="radio"]',function(){var b=a('input:radio[name="ssl"]:checked').val();if("https"===b){var c=a('input:radio[name="domain"]:checked').val();"subdomain"===c&&a('input[name="domain"][value="path"]').attr("checked",!0),a(".subdomain-wrap input").attr("disabled",!0),a(".subdomain-wrap").addClass("disabled")}else a(".subdomain-wrap input").removeAttr("disabled"),a(".subdomain-wrap").removeClass("disabled")}),a(".url-preview").on("change","input",function(){e()}),a("#tab-media > .as3cf-bucket-error").detach().insertAfter(".as3cf-bucket-container h3"),a("body").on("click",".bucket-action-manual",function(c){c.preventDefault(),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-manual").show().siblings().hide()}),a("body").on("click",".bucket-action-browse",function(c){c.preventDefault(),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-select").show().siblings().hide(),as3cf.buckets.loadList()}),a("body").on("click",".bucket-action-create",function(c){c.preventDefault(),a(".as3cf-bucket-name").val(""),a(".as3cf-invalid-bucket-name").html(""),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-create").show().siblings().hide()}),a("body").on("click",".bucket-action-cancel",function(a){a.preventDefault(),as3cf.buckets.resetModal()}),a("body").on("click",".bucket-action-save",function(a){a.preventDefault(),as3cf.buckets.saveManual()}),a("body").on("click",'.as3cf-create-bucket-form button[type="submit"]',function(a){a.preventDefault(),as3cf.buckets.create()}),a("body").on("click",".bucket-action-refresh",function(a){a.preventDefault(),as3cf.buckets.loadList(!0)}),a("body").on("click",".as3cf-bucket-list a",function(b){b.preventDefault(),as3cf.buckets.saveSelected(a(this))}),a(".as3cf-bucket-container").on("click","a.js-link",function(b){return b.preventDefault(),window.open(a(this).attr("href")),!1}),a("body").on("as3cf-modal-open",function(c,d){if(".as3cf-bucket-container."+b.prefix===d){as3cf.buckets.resetModal();var e=a(".as3cf-bucket-manual h3").data("modal-title");a(".as3cf-bucket-manual h3").text(e),as3cf.buckets.disabledButtons()}}),as3cf.buckets.disabledButtons(),a("body").on("input keyup",".as3cf-create-bucket-form .as3cf-bucket-name",function(){var c=a(this).val(),d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form");as3cf.buckets.isValidName(c)?d.find("button[type=submit]").removeAttr("disabled"):d.find("button[type=submit]").attr("disabled",!0),as3cf.buckets.updateNameNotice(c)}),a("body").on("input keyup",".as3cf-manual-save-bucket-form .as3cf-bucket-name",function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");c.find(".as3cf-bucket-name").val().length<as3cf.buckets.validLength?c.find("button[type=submit]").attr("disabled",!0):c.find("button[type=submit]").removeAttr("disabled")})})}(jQuery,as3cfModal);
assets/sass/modal.scss CHANGED
@@ -76,5 +76,4 @@
76
 
77
  body.as3cf-modal-open {
78
  overflow: hidden;
79
- padding-right: 15px;
80
  }
76
 
77
  body.as3cf-modal-open {
78
  overflow: hidden;
 
79
  }
assets/sass/styles.scss CHANGED
@@ -56,7 +56,7 @@
56
  .as3cf-notice, .error, .updated, .updated.show {
57
  display: none;
58
  }
59
- .fatal .error, .dbrains-api-down {
60
  display: block;
61
  }
62
  }
@@ -488,6 +488,7 @@
488
  }
489
 
490
  #tab-support {
 
491
  .as3cf-sidebar {
492
  top: 11px;
493
  }
@@ -549,11 +550,6 @@
549
  line-height: 1.4;
550
  }
551
 
552
- ul {
553
- margin-left: 20px;
554
- list-style-type: disc;
555
- }
556
-
557
  li {
558
  line-height: 1.4;
559
  }
@@ -579,6 +575,10 @@
579
  margin-bottom: 0.3em;
580
  }
581
 
 
 
 
 
582
  &.submit-button {
583
  margin-bottom: 1em;
584
  }
@@ -637,15 +637,8 @@
637
  (min-resolution: 1.3dppx) {
638
 
639
  .as3cf-banner {
640
- background-image: url(../img/snail@2x.jpg);
641
- background-size: 292px 165px;
642
- width: 292px;
643
- height: 165px;
644
- display: block;
645
-
646
- img {
647
- display: none;
648
- }
649
  }
650
  }
651
 
@@ -661,12 +654,64 @@
661
  * Misc
662
  */
663
  .as3cf-banner {
664
- img {
665
- display: block;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
666
  }
667
  }
668
 
669
  .aws-compatibility-notice.error {
670
  clear: both;
671
  margin: 5px 20px 5px 0;
 
 
 
 
 
 
672
  }
56
  .as3cf-notice, .error, .updated, .updated.show {
57
  display: none;
58
  }
59
+ .fatal .error, .as3cf-notice.important, .dbrains-api-down {
60
  display: block;
61
  }
62
  }
488
  }
489
 
490
  #tab-support {
491
+ min-height: 900px;
492
  .as3cf-sidebar {
493
  top: 11px;
494
  }
550
  line-height: 1.4;
551
  }
552
 
 
 
 
 
 
553
  li {
554
  line-height: 1.4;
555
  }
575
  margin-bottom: 0.3em;
576
  }
577
 
578
+ input[type=text], input[type=email] {
579
+ width: 100%;
580
+ }
581
+
582
  &.submit-button {
583
  margin-bottom: 1em;
584
  }
637
  (min-resolution: 1.3dppx) {
638
 
639
  .as3cf-banner {
640
+ background-image: url(../img/snail-banner@2x.jpg);
641
+ background-size: 292px 156px;
 
 
 
 
 
 
 
642
  }
643
  }
644
 
654
  * Misc
655
  */
656
  .as3cf-banner {
657
+ margin-top: 28px;
658
+ width: 292px;
659
+ height: 156px;
660
+ display: block;
661
+ background-image: url(../img/snail-banner.jpg);
662
+ position: relative;
663
+
664
+ h1 {
665
+ font-size: 28px;
666
+ color: #fff;
667
+ font-weight: 200;
668
+ margin: 0;
669
+ position: absolute;
670
+ bottom: 25px;
671
+ left: 20px;
672
+ text-decoration: none;
673
+ }
674
+ }
675
+
676
+ .as3cf-upgrade-details {
677
+ background-color: #73833b;
678
+ padding: 20px;
679
+ color: #fff;
680
+ font-size: 13px;
681
+ margin: 0;
682
+ display: block;
683
+ text-decoration: none;
684
+
685
+ p {
686
+ margin: 0;
687
+ }
688
+
689
+ a {
690
+ color: #fff;
691
+ font-weight: bold;
692
+ text-decoration: none;
693
+ font-size: 16px;
694
+
695
+ &:hover {
696
+ color: #fff;
697
+ opacity: 0.9;
698
+ }
699
+ }
700
+
701
+ ul {
702
+ margin-top: 0;
703
+ margin-left: 16px;
704
+ list-style-type: disc;
705
  }
706
  }
707
 
708
  .aws-compatibility-notice.error {
709
  clear: both;
710
  margin: 5px 20px 5px 0;
711
+ }
712
+
713
+ .as3cf-bucket-error {
714
+ span.title {
715
+ font-weight: bold;
716
+ }
717
  }
classes/amazon-s3-and-cloudfront.php CHANGED
@@ -47,6 +47,11 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
47
  */
48
  public $hook_suffix;
49
 
 
 
 
 
 
50
  const DEFAULT_ACL = 'public-read';
51
  const PRIVATE_ACL = 'private';
52
  const DEFAULT_EXPIRES = 900;
@@ -205,6 +210,10 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
205
  $region = $this->get_bucket_region( $bucket );
206
  }
207
 
 
 
 
 
208
  return $region;
209
  }
210
 
@@ -240,11 +249,21 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
240
  return $ssl;
241
  }
242
 
 
 
243
  if ( 'bucket' == $key && defined( 'AS3CF_BUCKET' ) ) {
244
- return AS3CF_BUCKET;
245
- }
 
 
 
 
 
 
 
246
 
247
- $value = parent::get_setting( $key, $default );
 
248
 
249
  return apply_filters( 'as3cf_setting_' . $key, $value );
250
  }
@@ -362,44 +381,6 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
362
  $this->end_ajax( $out );
363
  }
364
 
365
- /**
366
- * Find backup images and add to array for removal
367
- *
368
- * @param int $post_id
369
- * @param array $objects
370
- * @param string $path
371
- */
372
- function prepare_backup_size_images_to_remove( $post_id, &$objects, $path ) {
373
- $backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true );
374
-
375
- if ( is_array( $backup_sizes ) ) {
376
- foreach ( $backup_sizes as $size ) {
377
- $objects[] = array(
378
- 'Key' => path_join( $path, $size['file'] )
379
- );
380
- }
381
- }
382
- }
383
-
384
- /**
385
- * Find intermediate size images and add to array for removal
386
- *
387
- * @param int $post_id
388
- * @param array $objects
389
- * @param string $path
390
- */
391
- function prepare_intermediate_images_to_remove( $post_id, &$objects, $path ) {
392
- $intermediate_images = get_intermediate_image_sizes();
393
-
394
- foreach ( $intermediate_images as $size ) {
395
- if ( $intermediate = image_get_intermediate_size( $post_id, $size ) ) {
396
- $objects[] = array(
397
- 'Key' => path_join( $path, $intermediate['file'] )
398
- );
399
- }
400
- }
401
- }
402
-
403
  /**
404
  * Delete bulk objects from an S3 bucket
405
  *
@@ -427,65 +408,34 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
427
  }
428
  }
429
 
430
- /**
431
- * Remove any HDiPi image versions from S3 if they exist
432
- *
433
- * @param string $region
434
- * @param string $bucket
435
- * @param array $objects array of image file that could possibly have HDiPi versions
436
- */
437
- function maybe_remove_hdipi_images_from_s3( $region, $bucket, $objects ) {
438
- if ( $objects ) {
439
- $hidpi_images = array();
440
- foreach ( $objects as $object ) {
441
- $hidpi_images[] = array(
442
- 'Key' => $this->get_hidpi_file_path( $object['Key'] )
443
- );
444
- }
445
-
446
- // Try removing any @2x images but ignore any errors
447
- $this->delete_s3_objects( $region, $bucket, $hidpi_images );
448
- }
449
- }
450
-
451
  /**
452
  * Removes an attachment's files from S3.
453
  *
454
- * @param int $post_id
455
- * @param array $s3object
456
- * @param null|string $file optional file override of $s3object['key']
457
- * @param bool $remove_backup_sizes remove previous edited image versions
458
- * @param bool $log_error
459
- * @param bool $return_on_error
460
- * @param bool $force_new_s3_client if we are deleting in bulk, force new S3 client
461
  * to cope with possible different regions
462
  */
463
- function remove_attachment_files_from_s3( $post_id, $s3object, $file = null, $remove_backup_sizes = true, $log_error = false, $return_on_error = false, $force_new_s3_client = false ) {
464
- if ( is_null( $file ) ) {
465
- $file = $s3object['key'];
466
- }
467
-
468
  $prefix = trailingslashit( dirname( $s3object['key'] ) );
469
-
470
  $bucket = $s3object['bucket'];
471
  $region = $this->get_s3object_region( $s3object );
 
 
472
  if ( is_wp_error( $region ) ) {
473
  $region = '';
474
  }
475
 
476
  $objects_to_remove = array();
477
 
478
- $objects_to_remove[] = array(
479
- 'Key' => path_join( $prefix, basename( $file ) )
480
- );
481
- // get any image size files to remove
482
- $this->prepare_intermediate_images_to_remove( $post_id, $objects_to_remove, $prefix );
483
- if ( $remove_backup_sizes ) {
484
- // Remove backup images
485
- $this->prepare_backup_size_images_to_remove( $post_id, $objects, $prefix );
486
  }
487
- // remove any HDiPi iamhges
488
- $this->maybe_remove_hdipi_images_from_s3( $region, $bucket, $objects_to_remove );
489
 
490
  // finally delete the objects from S3
491
  $this->delete_s3_objects( $region, $bucket, $objects_to_remove, $log_error, $return_on_error, $force_new_s3_client );
@@ -507,7 +457,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
507
  return;
508
  }
509
 
510
- $this->remove_attachment_files_from_s3( $post_id, $s3object, null, true, true, true, $force_new_s3_client );
511
 
512
  delete_post_meta( $post_id, 'amazonS3_info' );
513
  }
@@ -551,10 +501,11 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
551
  * @param string|null $file_path
552
  * @param bool $force_new_s3_client if we are uploading in bulk, force new S3 client
553
  * to cope with possible different regions
 
554
  *
555
  * @return array|WP_Error $s3object
556
  */
557
- function upload_attachment_to_s3( $post_id, $data = null, $file_path = null, $force_new_s3_client = false ) {
558
  if ( is_null( $data ) ) {
559
  $data = wp_get_attachment_metadata( $post_id, true );
560
  }
@@ -628,17 +579,18 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
628
 
629
  $s3client = $this->get_s3client( $region, $force_new_s3_client );
630
 
631
- $args = apply_filters( 'as3cf_object_meta', array(
632
  'Bucket' => $bucket,
633
  'Key' => $prefix . $file_name,
634
  'SourceFile' => $file_path,
635
  'ACL' => $acl,
636
- ), $post_id );
637
 
638
  // If far future expiration checked (10 years)
639
  if ( $this->get_setting( 'expires' ) ) {
640
  $args['Expires'] = date( 'D, d M Y H:i:s O', time() + 315360000 );
641
  }
 
642
 
643
  do_action( 'as3cf_upload_attachment_pre_remove', $post_id, $s3object, $prefix, $args );
644
 
@@ -661,51 +613,20 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
661
 
662
  add_post_meta( $post_id, 'amazonS3_info', $s3object );
663
 
 
664
  $additional_images = array();
665
 
666
- if ( isset( $data['thumb'] ) && $data['thumb'] ) {
667
- $path = str_replace( $file_name, $data['thumb'], $file_path );
668
- if ( file_exists( $path ) && ! in_array( $path, $files_to_remove ) ) {
669
  $additional_images[] = array(
670
- 'Key' => $prefix . $data['thumb'],
671
- 'SourceFile' => $path,
672
  );
673
 
674
- $files_to_remove[] = $path;
675
- }
676
- } else if ( ! empty( $data['sizes'] ) ) {
677
- foreach ( $data['sizes'] as $size ) {
678
- $path = str_replace( $file_name, $size['file'], $file_path );
679
- if ( file_exists( $path ) && ! in_array( $path, $files_to_remove ) ) {
680
- $additional_images[] = array(
681
- 'Key' => $prefix . $size['file'],
682
- 'SourceFile' => $path,
683
- );
684
-
685
- $files_to_remove[] = $path;
686
- }
687
  }
688
  }
689
 
690
- // Because we're just looking at the filesystem for files with @2x
691
- // this should work with most HiDPI plugins
692
- if ( $this->get_setting( 'hidpi-images' ) ) {
693
- $hidpi_images = array();
694
-
695
- foreach ( $additional_images as $image ) {
696
- $hidpi_path = $this->get_hidpi_file_path( $image['SourceFile'] );
697
- if ( file_exists( $hidpi_path ) ) {
698
- $hidpi_images[] = array(
699
- 'Key' => $this->get_hidpi_file_path( $image['Key'] ),
700
- 'SourceFile' => $hidpi_path,
701
- );
702
- $files_to_remove[] = $hidpi_path;
703
- }
704
- }
705
-
706
- $additional_images = array_merge( $additional_images, $hidpi_images );
707
- }
708
-
709
  foreach ( $additional_images as $image ) {
710
  try {
711
  $args = array_merge( $args, $image );
@@ -717,17 +638,19 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
717
  }
718
  }
719
 
720
- if ( $this->get_setting( 'remove-local-file' ) ) {
721
- if ( isset( $_POST['action'] ) && 'image-editor' == sanitize_key( $_POST['action'] ) && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
722
- // remove original main image after edit
723
- $meta = get_post_meta( $post_id, '_wp_attachment_metadata', true );
724
- $original_file = str_replace( $file_name, basename( $meta['file'] ), $file_path );
725
- if ( file_exists( $original_file ) && ! in_array( $original_file, $files_to_remove ) ) {
726
- $files_to_remove[] = $original_file;
 
 
727
  }
 
 
728
  }
729
-
730
- $this->remove_local_files( $files_to_remove );
731
  }
732
 
733
  return $s3object;
@@ -1284,7 +1207,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1284
 
1285
  $result = $this->create_bucket( $bucket, $region );
1286
  if ( is_wp_error( $result ) ) {
1287
- $out = array( 'error' => $result->get_error_message() );
1288
 
1289
  $this->end_ajax( $out );
1290
  }
@@ -1292,30 +1215,11 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1292
  // check if we were previously selecting a bucket manually via the input
1293
  $previous_manual_bucket_select = $this->get_setting( 'manual_bucket', false );
1294
 
1295
- $region = $this->save_bucket( $bucket, $previous_manual_bucket_select, $region );
1296
-
1297
- if ( ! is_wp_error( $region ) ) {
1298
- $out = array(
1299
- 'success' => '1',
1300
- '_nonce' => wp_create_nonce( 'as3cf-create-bucket' ),
1301
- 'region' => $region,
1302
- );
1303
-
1304
- // Delete transient to force write check
1305
- delete_site_transient( $this->plugin_prefix . '_bucket_writable' );
1306
-
1307
- $can_write = $this->check_write_permission( $bucket, $region );
1308
-
1309
- if ( is_wp_error( $can_write ) ) {
1310
- $out = array( 'error' => $can_write->get_error_message() );
1311
- } else {
1312
- $out['can_write'] = $can_write;
1313
- }
1314
- } else {
1315
- $out = array( 'error' => $region->get_error_message() );
1316
- }
1317
 
1318
- $this->end_ajax( $out );
1319
  }
1320
 
1321
  /**
@@ -1362,7 +1266,19 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1362
  $manual = true;
1363
  }
1364
 
1365
- $region = $this->save_bucket( $bucket, $manual );
 
 
 
 
 
 
 
 
 
 
 
 
1366
 
1367
  if ( ! is_wp_error( $region ) ) {
1368
  $out = array(
@@ -1370,23 +1286,41 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1370
  'region' => $region,
1371
  );
1372
 
1373
- // Delete transient to force write check
1374
- delete_site_transient( $this->plugin_prefix . '_bucket_writable' );
1375
 
1376
  $can_write = $this->check_write_permission( $bucket, $region );
1377
 
1378
  if ( is_wp_error( $can_write ) ) {
1379
- $out = array( 'error' => $can_write->get_error_message() );
1380
  } else {
1381
  $out['can_write'] = $can_write;
1382
  }
1383
  } else {
1384
- $out = array( 'error' => $region->get_error_message() );
1385
  }
1386
 
1387
  $this->end_ajax( $out );
1388
  }
1389
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1390
  /**
1391
  * Perform custom actions before the setting is saved
1392
  *
@@ -1563,6 +1497,11 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1563
  * @return string
1564
  */
1565
  function translate_region( $region ) {
 
 
 
 
 
1566
  $region = strtolower( $region );
1567
 
1568
  switch ( $region ) {
@@ -1582,7 +1521,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1582
 
1583
  $result = $this->get_buckets();
1584
  if ( is_wp_error( $result ) ) {
1585
- $out = array( 'error' => $result->get_error_message() );
1586
  } else {
1587
  $out = array(
1588
  'success' => '1',
@@ -1625,10 +1564,8 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1625
  }
1626
  }
1627
 
1628
- $is_bucket_writable = get_site_transient( $this->plugin_prefix . '_bucket_writable' );
1629
-
1630
- if ( false !== $is_bucket_writable && $is_bucket_writable['bucket'] === $bucket ) {
1631
- return $is_bucket_writable['can_write'];
1632
  }
1633
 
1634
  $file_name = 'as3cf-permission-check.txt';
@@ -1663,7 +1600,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1663
  $can_write = true;
1664
  } catch ( Exception $e ) {
1665
  // if we encounter an error that isn't access denied, throw that error
1666
- if ( 'AccessDenied' != $e->getExceptionCode() ) {
1667
  $error_msg = sprintf( __( 'There was an error attempting to check the permissions of the bucket %s: %s', 'as3cf' ), $bucket, $e->getMessage() );
1668
  error_log( $error_msg );
1669
 
@@ -1674,12 +1611,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1674
  $can_write = false;
1675
  }
1676
 
1677
- // Cache the result
1678
- $is_bucket_writable = array(
1679
- 'bucket' => $bucket,
1680
- 'can_write' => $can_write,
1681
- );
1682
- set_site_transient( $this->plugin_prefix . '_bucket_writable', $is_bucket_writable, 5 * MINUTE_IN_SECONDS );
1683
 
1684
  return $can_write;
1685
  }
@@ -1727,12 +1659,12 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1727
  'as3cf',
1728
  array(
1729
  'strings' => array(
1730
- 'create_bucket_error' => __( 'Error creating bucket: ', 'as3cf' ),
1731
  'create_bucket_name_short' => __( 'Bucket name too short.', 'as3cf' ),
1732
  'create_bucket_name_long' => __( 'Bucket name too long.', 'as3cf' ),
1733
  'create_bucket_invalid_chars' => __( 'Invalid character. Bucket names can contain lowercase letters, numbers, periods and hyphens.', 'as3cf' ),
1734
- 'save_bucket_error' => __( 'Error saving bucket: ', 'as3cf' ),
1735
- 'get_buckets_error' => __( 'Error fetching buckets: ', 'as3cf' ),
1736
  'get_url_preview_error' => __( 'Error getting URL preview: ', 'as3cf' ),
1737
  'save_alert' => __( 'The changes you made will be lost if you navigate away from this page', 'as3cf' )
1738
  ),
@@ -2381,4 +2313,125 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2381
 
2382
  return false;
2383
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2384
  }
47
  */
48
  public $hook_suffix;
49
 
50
+ /**
51
+ * @var array Store if each bucket, used by the plugin and addons, is writable
52
+ */
53
+ protected static $buckets_check = array();
54
+
55
  const DEFAULT_ACL = 'public-read';
56
  const PRIVATE_ACL = 'private';
57
  const DEFAULT_EXPIRES = 900;
210
  $region = $this->get_bucket_region( $bucket );
211
  }
212
 
213
+ // Store the region for future use
214
+ parent::set_setting( 'region', $region );
215
+ $this->save_settings();
216
+
217
  return $region;
218
  }
219
 
249
  return $ssl;
250
  }
251
 
252
+ $value = parent::get_setting( $key, $default );
253
+
254
  if ( 'bucket' == $key && defined( 'AS3CF_BUCKET' ) ) {
255
+ $bucket = AS3CF_BUCKET;
256
+
257
+ if ( $bucket !== $value ) {
258
+ // Save the defined bucket
259
+ parent::set_setting( 'bucket', $bucket );
260
+ // Clear region
261
+ $this->remove_setting( 'region' );
262
+ $this->save_settings();
263
+ }
264
 
265
+ return $bucket;
266
+ }
267
 
268
  return apply_filters( 'as3cf_setting_' . $key, $value );
269
  }
381
  $this->end_ajax( $out );
382
  }
383
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
  /**
385
  * Delete bulk objects from an S3 bucket
386
  *
408
  }
409
  }
410
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411
  /**
412
  * Removes an attachment's files from S3.
413
  *
414
+ * @param int $post_id
415
+ * @param array $s3object
416
+ * @param bool $remove_backup_sizes remove previous edited image versions
417
+ * @param bool $log_error
418
+ * @param bool $return_on_error
419
+ * @param bool $force_new_s3_client if we are deleting in bulk, force new S3 client
 
420
  * to cope with possible different regions
421
  */
422
+ function remove_attachment_files_from_s3( $post_id, $s3object, $remove_backup_sizes = true, $log_error = false, $return_on_error = false, $force_new_s3_client = false ) {
 
 
 
 
423
  $prefix = trailingslashit( dirname( $s3object['key'] ) );
 
424
  $bucket = $s3object['bucket'];
425
  $region = $this->get_s3object_region( $s3object );
426
+ $paths = $this->get_attachment_file_paths( $post_id, false, false, $remove_backup_sizes );
427
+
428
  if ( is_wp_error( $region ) ) {
429
  $region = '';
430
  }
431
 
432
  $objects_to_remove = array();
433
 
434
+ foreach ( $paths as $path ) {
435
+ $objects_to_remove[] = array(
436
+ 'Key' => $prefix . basename( $path ),
437
+ );
 
 
 
 
438
  }
 
 
439
 
440
  // finally delete the objects from S3
441
  $this->delete_s3_objects( $region, $bucket, $objects_to_remove, $log_error, $return_on_error, $force_new_s3_client );
457
  return;
458
  }
459
 
460
+ $this->remove_attachment_files_from_s3( $post_id, $s3object, true, true, true, $force_new_s3_client );
461
 
462
  delete_post_meta( $post_id, 'amazonS3_info' );
463
  }
501
  * @param string|null $file_path
502
  * @param bool $force_new_s3_client if we are uploading in bulk, force new S3 client
503
  * to cope with possible different regions
504
+ * @param bool $remove_local_files
505
  *
506
  * @return array|WP_Error $s3object
507
  */
508
+ function upload_attachment_to_s3( $post_id, $data = null, $file_path = null, $force_new_s3_client = false, $remove_local_files = true ) {
509
  if ( is_null( $data ) ) {
510
  $data = wp_get_attachment_metadata( $post_id, true );
511
  }
579
 
580
  $s3client = $this->get_s3client( $region, $force_new_s3_client );
581
 
582
+ $args = array(
583
  'Bucket' => $bucket,
584
  'Key' => $prefix . $file_name,
585
  'SourceFile' => $file_path,
586
  'ACL' => $acl,
587
+ );
588
 
589
  // If far future expiration checked (10 years)
590
  if ( $this->get_setting( 'expires' ) ) {
591
  $args['Expires'] = date( 'D, d M Y H:i:s O', time() + 315360000 );
592
  }
593
+ $args = apply_filters( 'as3cf_object_meta', $args, $post_id );
594
 
595
  do_action( 'as3cf_upload_attachment_pre_remove', $post_id, $s3object, $prefix, $args );
596
 
613
 
614
  add_post_meta( $post_id, 'amazonS3_info', $s3object );
615
 
616
+ $file_paths = $this->get_attachment_file_paths( $post_id, true, $data );
617
  $additional_images = array();
618
 
619
+ foreach ( $file_paths as $file_path ) {
620
+ if ( ! in_array( $file_path, $files_to_remove ) ) {
 
621
  $additional_images[] = array(
622
+ 'Key' => $prefix . basename( $file_path ),
623
+ 'SourceFile' => $file_path,
624
  );
625
 
626
+ $files_to_remove[] = $file_path;
 
 
 
 
 
 
 
 
 
 
 
 
627
  }
628
  }
629
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
630
  foreach ( $additional_images as $image ) {
631
  try {
632
  $args = array_merge( $args, $image );
638
  }
639
  }
640
 
641
+ if ( $remove_local_files ) {
642
+ if ( $this->get_setting( 'remove-local-file' ) ) {
643
+ if ( isset( $_POST['action'] ) && 'image-editor' == sanitize_key( $_POST['action'] ) && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
644
+ // remove original main image after edit
645
+ $meta = get_post_meta( $post_id, '_wp_attachment_metadata', true );
646
+ $original_file = trailingslashit( dirname( $file_path ) ) . basename( $meta['file'] );
647
+ if ( file_exists( $original_file ) && ! in_array( $original_file, $files_to_remove ) ) {
648
+ $files_to_remove[] = $original_file;
649
+ }
650
  }
651
+
652
+ $this->remove_local_files( $files_to_remove );
653
  }
 
 
654
  }
655
 
656
  return $s3object;
1207
 
1208
  $result = $this->create_bucket( $bucket, $region );
1209
  if ( is_wp_error( $result ) ) {
1210
+ $out = $this->prepare_bucket_error( $result, false );
1211
 
1212
  $this->end_ajax( $out );
1213
  }
1215
  // check if we were previously selecting a bucket manually via the input
1216
  $previous_manual_bucket_select = $this->get_setting( 'manual_bucket', false );
1217
 
1218
+ $args = array(
1219
+ '_nonce' => wp_create_nonce( 'as3cf-create-bucket' )
1220
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1221
 
1222
+ $this->save_bucket_for_ajax( $bucket, $previous_manual_bucket_select, $region, $args );
1223
  }
1224
 
1225
  /**
1266
  $manual = true;
1267
  }
1268
 
1269
+ $this->save_bucket_for_ajax( $bucket, $manual );
1270
+ }
1271
+
1272
+ /**
1273
+ * Wrapper method for saving a bucket when creating or selecting
1274
+ *
1275
+ * @param string $bucket
1276
+ * @param bool|false $manual_select
1277
+ * @param null|string $region
1278
+ * @param array $defaults
1279
+ */
1280
+ function save_bucket_for_ajax( $bucket, $manual_select = false, $region = null, $defaults = array() ) {
1281
+ $region = $this->save_bucket( $bucket, $manual_select, $region );
1282
 
1283
  if ( ! is_wp_error( $region ) ) {
1284
  $out = array(
1286
  'region' => $region,
1287
  );
1288
 
1289
+ $out = wp_parse_args( $out, $defaults );
 
1290
 
1291
  $can_write = $this->check_write_permission( $bucket, $region );
1292
 
1293
  if ( is_wp_error( $can_write ) ) {
1294
+ $out = $this->prepare_bucket_error( $can_write );
1295
  } else {
1296
  $out['can_write'] = $can_write;
1297
  }
1298
  } else {
1299
+ $out = $this->prepare_bucket_error( $region );
1300
  }
1301
 
1302
  $this->end_ajax( $out );
1303
  }
1304
 
1305
+ /**
1306
+ * Prepare the bucket error before returning to JS
1307
+ *
1308
+ * @param WP_Error $object
1309
+ * @param bool $single Are we dealing with a single bucket?
1310
+ *
1311
+ * @return array
1312
+ */
1313
+ function prepare_bucket_error( $object, $single = true ) {
1314
+ if ( 'Access Denied' === $object->get_error_message() ) {
1315
+ // If the bucket error is access denied, show our notice message
1316
+ $out = array( 'error' => $this->get_access_denied_notice_message( $single ) );
1317
+ } else {
1318
+ $out = array( 'error' => $object->get_error_message() );
1319
+ }
1320
+
1321
+ return $out;
1322
+ }
1323
+
1324
  /**
1325
  * Perform custom actions before the setting is saved
1326
  *
1497
  * @return string
1498
  */
1499
  function translate_region( $region ) {
1500
+ if ( ! is_string( $region ) ) {
1501
+ // Don't translate any region errors
1502
+ return $region;
1503
+ }
1504
+
1505
  $region = strtolower( $region );
1506
 
1507
  switch ( $region ) {
1521
 
1522
  $result = $this->get_buckets();
1523
  if ( is_wp_error( $result ) ) {
1524
+ $out = $this->prepare_bucket_error( $result, false );
1525
  } else {
1526
  $out = array(
1527
  'success' => '1',
1564
  }
1565
  }
1566
 
1567
+ if ( isset( self::$buckets_check[ $bucket ] ) ) {
1568
+ return self::$buckets_check[ $bucket ];
 
 
1569
  }
1570
 
1571
  $file_name = 'as3cf-permission-check.txt';
1600
  $can_write = true;
1601
  } catch ( Exception $e ) {
1602
  // if we encounter an error that isn't access denied, throw that error
1603
+ if ( ! $e instanceof Aws\Common\Exception\ServiceResponseException || 'AccessDenied' !== $e->getExceptionCode() ) {
1604
  $error_msg = sprintf( __( 'There was an error attempting to check the permissions of the bucket %s: %s', 'as3cf' ), $bucket, $e->getMessage() );
1605
  error_log( $error_msg );
1606
 
1611
  $can_write = false;
1612
  }
1613
 
1614
+ self::$buckets_check[ $bucket ] = $can_write;
 
 
 
 
 
1615
 
1616
  return $can_write;
1617
  }
1659
  'as3cf',
1660
  array(
1661
  'strings' => array(
1662
+ 'create_bucket_error' => __( 'Error creating bucket', 'as3cf' ),
1663
  'create_bucket_name_short' => __( 'Bucket name too short.', 'as3cf' ),
1664
  'create_bucket_name_long' => __( 'Bucket name too long.', 'as3cf' ),
1665
  'create_bucket_invalid_chars' => __( 'Invalid character. Bucket names can contain lowercase letters, numbers, periods and hyphens.', 'as3cf' ),
1666
+ 'save_bucket_error' => __( 'Error saving bucket', 'as3cf' ),
1667
+ 'get_buckets_error' => __( 'Error fetching buckets', 'as3cf' ),
1668
  'get_url_preview_error' => __( 'Error getting URL preview: ', 'as3cf' ),
1669
  'save_alert' => __( 'The changes you made will be lost if you navigate away from this page', 'as3cf' )
1670
  ),
2313
 
2314
  return false;
2315
  }
2316
+
2317
+ /**
2318
+ * Get all the table prefixes for the blogs in the site. MS compatible
2319
+ *
2320
+ * @param array $exclude_blog_ids blog ids to exclude
2321
+ *
2322
+ * @return array associative array with blog ID as key, prefix as value
2323
+ */
2324
+ function get_all_blog_table_prefixes( $exclude_blog_ids = array() ) {
2325
+ global $wpdb;
2326
+ $prefix = $wpdb->prefix;
2327
+
2328
+ $table_prefixes = array();
2329
+
2330
+ if ( ! in_array( 1, $exclude_blog_ids ) ) {
2331
+ $table_prefixes[1] = $prefix;
2332
+ }
2333
+
2334
+ if ( is_multisite() ) {
2335
+ $blog_ids = $this->get_blog_ids();
2336
+ foreach ( $blog_ids as $blog_id ) {
2337
+ if ( in_array( $blog_id, $exclude_blog_ids ) ) {
2338
+ continue;
2339
+ }
2340
+ $table_prefixes[ $blog_id ] = $wpdb->get_blog_prefix( $blog_id );
2341
+ }
2342
+ }
2343
+
2344
+ return $table_prefixes;
2345
+ }
2346
+
2347
+ /**
2348
+ * Get file paths for all attachment versions.
2349
+ *
2350
+ * @param int $attachment_id
2351
+ * @param bool $exists_locally
2352
+ * @param array|bool $meta
2353
+ * @param bool $include_backups
2354
+ *
2355
+ * @return array
2356
+ */
2357
+ public function get_attachment_file_paths( $attachment_id, $exists_locally = true, $meta = false, $include_backups = true ) {
2358
+ $paths = array();
2359
+ $file_path = get_attached_file( $attachment_id, true );
2360
+ $file_name = basename( $file_path );
2361
+ $backups = get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true );
2362
+
2363
+ if ( ! $meta ) {
2364
+ $meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
2365
+ }
2366
+
2367
+ $original_file = $file_path; // Not all attachments will have meta
2368
+
2369
+ if ( isset( $meta['file'] ) ) {
2370
+ $original_file = str_replace( $file_name, basename( $meta['file'] ), $file_path );
2371
+ }
2372
+
2373
+ // Original file
2374
+ $paths[] = $original_file;
2375
+
2376
+ // Sizes
2377
+ if ( isset( $meta['sizes'] ) ) {
2378
+ foreach ( $meta['sizes'] as $size ) {
2379
+ if ( isset( $size['file'] ) ) {
2380
+ $paths[] = str_replace( $file_name, $size['file'], $file_path );
2381
+ }
2382
+ }
2383
+ }
2384
+
2385
+ // Thumb
2386
+ if ( isset( $meta['thumb'] ) ) {
2387
+ $paths[] = str_replace( $file_name, $meta['thumb'], $file_path );
2388
+ }
2389
+
2390
+ // Backups
2391
+ if ( $include_backups && is_array( $backups ) ) {
2392
+ foreach ( $backups as $backup ) {
2393
+ $paths[] = str_replace( $file_name, $backup['file'], $file_path );
2394
+ }
2395
+ }
2396
+
2397
+ // HiDPI
2398
+ if ( $this->get_setting( 'hidpi-images' ) ) {
2399
+ foreach ( $paths as $path ) {
2400
+ $paths[] = $this->get_hidpi_file_path( $path );
2401
+ }
2402
+ }
2403
+
2404
+ // Remove duplicates
2405
+ $paths = array_unique( $paths );
2406
+
2407
+ // Remove paths that don't exist
2408
+ if ( $exists_locally ) {
2409
+ foreach ( $paths as $key => $path ) {
2410
+ if ( ! file_exists( $path ) ) {
2411
+ unset( $paths[ $key ] );
2412
+ }
2413
+ }
2414
+ }
2415
+
2416
+ return $paths;
2417
+ }
2418
+
2419
+ /**
2420
+ * Get the access denied bucket error notice message
2421
+ *
2422
+ * @param bool $single
2423
+ *
2424
+ * @return string
2425
+ */
2426
+ function get_access_denied_notice_message( $single = true ) {
2427
+ $quick_start = sprintf( '<a class="js-link" href="%s">%s</a>', 'https://deliciousbrains.com/wp-offload-s3/doc/quick-start-guide/', __( 'Quick Start Guide', 'as3cf' ) );
2428
+
2429
+ $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.", 'as3cf' ), $quick_start );
2430
+ if ( ! $single ) {
2431
+ $message = sprintf( __( "Looks like we don't have access to the buckets. 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.", 'as3cf' ), $quick_start );
2432
+
2433
+ }
2434
+
2435
+ return $message;
2436
+ }
2437
  }
classes/as3cf-plugin-compatibility.php CHANGED
@@ -38,6 +38,12 @@ class AS3CF_Plugin_Compatibility {
38
  * Register the compatibility hooks
39
  */
40
  function compatibility_init() {
 
 
 
 
 
 
41
  /*
42
  * WP_Image_Editor
43
  * /wp-includes/class-wp-image-editor.php
@@ -58,6 +64,33 @@ class AS3CF_Plugin_Compatibility {
58
  add_filter( 'as3cf_get_attached_file', array( $this, 'regenerate_thumbnails_download_file' ), 10, 4 );
59
  }
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  /**
62
  * Allow the WordPress Image Editor to remove edited version of images
63
  * if the original image is being restored and 'IMAGE_EDIT_OVERWRITE' is set
@@ -68,10 +101,15 @@ class AS3CF_Plugin_Compatibility {
68
  * @param array $args
69
  */
70
  function image_editor_remove_files( $post_id, $s3object, $prefix, $args ) {
71
- if ( isset( $_POST['do'] ) && 'restore' == $_POST['do'] && defined( 'IMAGE_EDIT_OVERWRITE' ) && IMAGE_EDIT_OVERWRITE ) {
72
- $meta = get_post_meta( $post_id, '_wp_attachment_metadata', true );
73
- $this->as3cf->remove_attachment_files_from_s3( $post_id, $s3object, $meta['file'] );
74
  }
 
 
 
 
 
 
75
  }
76
 
77
  /**
38
  * Register the compatibility hooks
39
  */
40
  function compatibility_init() {
41
+ /*
42
+ * Legacy filter
43
+ * 'as3cf_get_attached_file_copy_back_to_local'
44
+ */
45
+ add_filter( 'as3cf_get_attached_file', array( $this, 'legacy_copy_back_to_local'), 10, 4 );
46
+
47
  /*
48
  * WP_Image_Editor
49
  * /wp-includes/class-wp-image-editor.php
64
  add_filter( 'as3cf_get_attached_file', array( $this, 'regenerate_thumbnails_download_file' ), 10, 4 );
65
  }
66
 
67
+ /**
68
+ * Allow any process to trigger the copy back to local with
69
+ * the filter 'as3cf_get_attached_file_copy_back_to_local'
70
+ *
71
+ * @param string $url
72
+ * @param string $file
73
+ * @param int $attachment_id
74
+ * @param array $s3_object
75
+ *
76
+ * @return string
77
+ */
78
+ function legacy_copy_back_to_local( $url, $file, $attachment_id, $s3_object ) {
79
+ $copy_back_to_local = apply_filters( 'as3cf_get_attached_file_copy_back_to_local', false, $file, $attachment_id, $s3_object );
80
+ if ( false === $copy_back_to_local ) {
81
+ // Not copying back file
82
+ return $url;
83
+ }
84
+
85
+ if ( ( $file = $this->copy_s3_file_to_server( $s3_object, $file ) ) ) {
86
+ // Return the file if successfully downloaded from S3
87
+ return $file;
88
+ };
89
+
90
+ // Return S3 URL as a fallback
91
+ return $url;
92
+ }
93
+
94
  /**
95
  * Allow the WordPress Image Editor to remove edited version of images
96
  * if the original image is being restored and 'IMAGE_EDIT_OVERWRITE' is set
101
  * @param array $args
102
  */
103
  function image_editor_remove_files( $post_id, $s3object, $prefix, $args ) {
104
+ if ( ! isset( $_POST['do'] ) || 'restore' !== $_POST['do'] ) {
105
+ return;
 
106
  }
107
+
108
+ if ( ! defined( 'IMAGE_EDIT_OVERWRITE' ) || ! IMAGE_EDIT_OVERWRITE ) {
109
+ return;
110
+ }
111
+
112
+ $this->as3cf->remove_attachment_files_from_s3( $post_id, $s3object, false );
113
  }
114
 
115
  /**
classes/as3cf-upgrade.php CHANGED
@@ -207,7 +207,7 @@ class AS3CF_Upgrade {
207
  $error_count = isset( $session['error_count'] ) ? $session['error_count'] : 0;
208
 
209
  // get the table prefixes for all the blogs
210
- $table_prefixes = $this->get_all_blog_table_prefixes( $processed_blog_ids );
211
 
212
  $all_attachments = array();
213
  $all_count = 0;
@@ -299,7 +299,7 @@ class AS3CF_Upgrade {
299
  */
300
  function count_all_attachments_without_region() {
301
  // get the table prefixes for all the blogs
302
- $table_prefixes = $this->get_all_blog_table_prefixes();
303
  $all_count = 0;
304
 
305
  foreach ( $table_prefixes as $blog_id => $table_prefix ) {
207
  $error_count = isset( $session['error_count'] ) ? $session['error_count'] : 0;
208
 
209
  // get the table prefixes for all the blogs
210
+ $table_prefixes = $this->as3cf->get_all_blog_table_prefixes( $processed_blog_ids );
211
 
212
  $all_attachments = array();
213
  $all_count = 0;
299
  */
300
  function count_all_attachments_without_region() {
301
  // get the table prefixes for all the blogs
302
+ $table_prefixes = $this->as3cf->get_all_blog_table_prefixes();
303
  $all_count = 0;
304
 
305
  foreach ( $table_prefixes as $blog_id => $table_prefix ) {
classes/wp-aws-compatibility-check.php CHANGED
@@ -254,6 +254,19 @@ if ( ! class_exists( 'WP_AWS_Compatibility_Check' ) ) {
254
  return true;
255
  }
256
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
  /**
258
  * Get the compatibility error message
259
  *
@@ -386,6 +399,13 @@ if ( ! class_exists( 'WP_AWS_Compatibility_Check' ) ) {
386
  return;
387
  }
388
 
 
 
 
 
 
 
 
389
  $this->get_admin_notice();
390
  }
391
 
254
  return true;
255
  }
256
 
257
+ /**
258
+ * Check the parent plugin is at a specific version
259
+ *
260
+ * @param string $version
261
+ *
262
+ * @return bool
263
+ */
264
+ function is_parent_plugin_at_version( $version ) {
265
+ $current_parent_plugin_version = isset( $GLOBALS['aws_meta'][ $this->parent_plugin_slug ]['version'] ) ? $GLOBALS['aws_meta'][ $this->parent_plugin_slug ]['version'] : 0;
266
+
267
+ return version_compare( $current_parent_plugin_version, $version, '>=' );
268
+ }
269
+
270
  /**
271
  * Get the compatibility error message
272
  *
399
  return;
400
  }
401
 
402
+ global $pagenow;
403
+
404
+ if ( 'update.php' === $pagenow && isset( $_GET['action'] ) && 'install-plugin' === $_GET['action'] ) {
405
+ // Don't show notice when installing plugins
406
+ return;
407
+ }
408
+
409
  $this->get_admin_notice();
410
  }
411
 
languages/amazon-s3-and-cloudfront-en.pot CHANGED
@@ -8,121 +8,142 @@ 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-07-08 12:57-0300\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"
15
  "Language: \n"
16
  "MIME-Version: 1.0\n"
17
- "Content-Type: text/plain; charset=CHARSET\n"
18
  "Content-Transfer-Encoding: 8bit\n"
19
 
20
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:79
21
  msgid "Offload S3"
22
  msgstr ""
23
 
24
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:80
25
  msgid "S3 and CloudFront"
26
  msgstr ""
27
 
28
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:568
29
  #, php-format
30
  msgid "File %s does not exist"
31
  msgstr ""
32
 
33
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:577
34
  #, php-format
35
  msgid "Mime type %s is not allowed"
36
  msgstr ""
37
 
38
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:653
39
  #, php-format
40
  msgid "Error uploading %s to S3: %s"
41
  msgstr ""
42
 
43
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1251
44
  msgid "Cheatin&#8217; eh?"
45
  msgstr ""
46
 
47
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1255
48
  msgid "You do not have sufficient permissions to access this page."
49
  msgstr ""
50
 
51
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1261
52
  msgid "No bucket name provided."
53
  msgstr ""
54
 
55
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1518
56
  #, php-format
57
  msgid "There was an error attempting to get the region of the bucket %s: %s"
58
  msgstr ""
59
 
60
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1635
61
  msgid ""
62
  "This is a test file to check if the user has write permission to S3. Delete "
63
  "me if found."
64
  msgstr ""
65
 
66
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1667
67
  #, php-format
68
  msgid ""
69
  "There was an error attempting to check the permissions of the bucket %s: %s"
70
  msgstr ""
71
 
72
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1730
73
- msgid "Error creating bucket: "
74
  msgstr ""
75
 
76
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1731
77
  msgid "Bucket name too short."
78
  msgstr ""
79
 
80
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1732
81
  msgid "Bucket name too long."
82
  msgstr ""
83
 
84
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1733
85
  msgid ""
86
  "Invalid character. Bucket names can contain lowercase letters, numbers, "
87
  "periods and hyphens."
88
  msgstr ""
89
 
90
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1734
91
- msgid "Error saving bucket: "
92
  msgstr ""
93
 
94
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1735
95
- msgid "Error fetching buckets: "
96
  msgstr ""
97
 
98
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1736
99
  msgid "Error getting URL preview: "
100
  msgstr ""
101
 
102
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1737
103
  msgid "The changes you made will be lost if you navigate away from this page"
104
  msgstr ""
105
 
106
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1795
107
  msgid "Cheatin' eh?"
108
  msgstr ""
109
 
110
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1898
111
  msgctxt "Show the media library tab"
112
  msgid "Media Library"
113
  msgstr ""
114
 
115
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1899
116
  msgctxt "Show the support tab"
117
  msgid "Support"
118
  msgstr ""
119
 
120
- #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:2035
121
  #, php-format
122
  msgid "The file %s has been given %s permissions on Amazon S3."
123
  msgstr ""
124
 
125
- #: builds/amazon-s3-and-cloudfront/classes/as3cf-plugin-compatibility.php:222
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  #, php-format
127
  msgid "There was an error attempting to download the file %s from S3: %s"
128
  msgstr ""
@@ -170,78 +191,78 @@ msgstr ""
170
  msgid "Every %d Minutes"
171
  msgstr ""
172
 
173
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:276
174
  msgid "deactivate"
175
  msgstr ""
176
 
177
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:277
178
  #, php-format
179
  msgid "You can %s the %s plugin to get rid of this notice."
180
  msgstr ""
181
 
182
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:280
183
  #, php-format
184
  msgid "%s has been disabled as it requires the %s plugin."
185
  msgstr ""
186
 
187
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:284
188
  msgid "which is currently disabled."
189
  msgstr ""
190
 
191
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:286
192
  msgid "It appears to be installed already."
193
  msgstr ""
194
 
195
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:288
196
  msgctxt "Activate plugin"
197
  msgid "Activate it now."
198
  msgstr ""
199
 
200
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:295
201
  #, php-format
202
  msgid "<a href=\"%s\">Install</a> and activate it."
203
  msgstr ""
204
 
205
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:306
206
  #, php-format
207
  msgid ""
208
  "%s has been disabled as it requires version %s or later of the %s plugin."
209
  msgstr ""
210
 
211
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:309
212
  #, php-format
213
  msgid "You currently have version %s installed."
214
  msgstr ""
215
 
216
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:316
217
  #, php-format
218
  msgid "A valid license for %s is required to update."
219
  msgstr ""
220
 
221
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:324
222
  msgid "Update to the latest version"
223
  msgstr ""
224
 
225
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:336
226
  #, php-format
227
  msgid ""
228
  "%1$s has been disabled because it is not a supported addon of the %2$s "
229
  "plugin."
230
  msgstr ""
231
 
232
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:345
233
  #, php-format
234
  msgid ""
235
  "%1$s has been disabled because it will not work with the version of the %2$s "
236
  "plugin installed. %1$s %3$s or later is required."
237
  msgstr ""
238
 
239
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:348
240
  #, php-format
241
  msgid "Update %s to the latest version"
242
  msgstr ""
243
 
244
- #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:403
245
  #, php-format
246
  msgid "The %s plugin has been deactivated."
247
  msgstr ""
@@ -362,15 +383,6 @@ msgstr ""
362
  msgid "Access Denied to Bucket"
363
  msgstr ""
364
 
365
- #: builds/amazon-s3-and-cloudfront/view/error-access.php:6
366
- #, php-format
367
- msgid ""
368
- "This could indicate your S3 policy is Read-Only. You need to go to <a href="
369
- "\"%s\">Identity and Access Management</a> in your AWS console and manage the "
370
- "policy for the user you're using for this plugin. Your policy should look "
371
- "something like the following:"
372
- msgstr ""
373
-
374
  #: builds/amazon-s3-and-cloudfront/view/settings.php:10
375
  msgid "Settings saved."
376
  msgstr ""
@@ -506,49 +518,66 @@ msgstr ""
506
  msgid "Save Changes"
507
  msgstr ""
508
 
509
- #: builds/amazon-s3-and-cloudfront/view/sidebar.php:6
510
- msgid "Pro Version?"
511
  msgstr ""
512
 
513
  #: builds/amazon-s3-and-cloudfront/view/sidebar.php:11
514
- msgid ""
515
- "We're working on a pro version that will include the following features:"
 
 
 
 
 
 
 
 
 
 
 
516
  msgstr ""
517
 
518
  #: builds/amazon-s3-and-cloudfront/view/sidebar.php:15
519
- msgid "Copy existing Media Library to S3"
520
  msgstr ""
521
 
522
  #: builds/amazon-s3-and-cloudfront/view/sidebar.php:16
523
- msgid "Serve theme JS & CSS from S3/CloudFront"
524
  msgstr ""
525
 
526
- #: builds/amazon-s3-and-cloudfront/view/sidebar.php:17
527
- msgid ""
528
- "WooCommerce & <abbr title=\"Easy Digital Downloads\">EDD</abbr> integration"
529
  msgstr ""
530
 
531
- #: builds/amazon-s3-and-cloudfront/view/sidebar.php:18
532
- msgid "Awesome email support"
533
  msgstr ""
534
 
535
- #: builds/amazon-s3-and-cloudfront/view/sidebar.php:22
 
 
 
 
 
 
 
536
  msgid "Your Email"
537
  msgstr ""
538
 
539
- #: builds/amazon-s3-and-cloudfront/view/sidebar.php:26
540
  msgid "First Name"
541
  msgstr ""
542
 
543
- #: builds/amazon-s3-and-cloudfront/view/sidebar.php:30
544
  msgid "Last Name"
545
  msgstr ""
546
 
547
- #: builds/amazon-s3-and-cloudfront/view/sidebar.php:37
548
- msgid "Send me news about a pro version"
549
  msgstr ""
550
 
551
- #: builds/amazon-s3-and-cloudfront/view/sidebar.php:41
552
  msgid ""
553
  "We promise we will not use your email for anything else and you can "
554
  "unsubscribe with 1-click anytime."
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-07-29 09:52-0300\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"
15
  "Language: \n"
16
  "MIME-Version: 1.0\n"
17
+ "Content-Type: text/plain; charset=UTF-8\n"
18
  "Content-Transfer-Encoding: 8bit\n"
19
 
20
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:84
21
  msgid "Offload S3"
22
  msgstr ""
23
 
24
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:85
25
  msgid "S3 and CloudFront"
26
  msgstr ""
27
 
28
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:519
29
  #, php-format
30
  msgid "File %s does not exist"
31
  msgstr ""
32
 
33
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:528
34
  #, php-format
35
  msgid "Mime type %s is not allowed"
36
  msgstr ""
37
 
38
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:605
39
  #, php-format
40
  msgid "Error uploading %s to S3: %s"
41
  msgstr ""
42
 
43
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1174
44
  msgid "Cheatin&#8217; eh?"
45
  msgstr ""
46
 
47
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1178
48
  msgid "You do not have sufficient permissions to access this page."
49
  msgstr ""
50
 
51
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1184
52
  msgid "No bucket name provided."
53
  msgstr ""
54
 
55
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1452
56
  #, php-format
57
  msgid "There was an error attempting to get the region of the bucket %s: %s"
58
  msgstr ""
59
 
60
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1572
61
  msgid ""
62
  "This is a test file to check if the user has write permission to S3. Delete "
63
  "me if found."
64
  msgstr ""
65
 
66
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1604
67
  #, php-format
68
  msgid ""
69
  "There was an error attempting to check the permissions of the bucket %s: %s"
70
  msgstr ""
71
 
72
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1662
73
+ msgid "Error creating bucket"
74
  msgstr ""
75
 
76
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1663
77
  msgid "Bucket name too short."
78
  msgstr ""
79
 
80
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1664
81
  msgid "Bucket name too long."
82
  msgstr ""
83
 
84
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1665
85
  msgid ""
86
  "Invalid character. Bucket names can contain lowercase letters, numbers, "
87
  "periods and hyphens."
88
  msgstr ""
89
 
90
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1666
91
+ msgid "Error saving bucket"
92
  msgstr ""
93
 
94
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1667
95
+ msgid "Error fetching buckets"
96
  msgstr ""
97
 
98
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1668
99
  msgid "Error getting URL preview: "
100
  msgstr ""
101
 
102
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1669
103
  msgid "The changes you made will be lost if you navigate away from this page"
104
  msgstr ""
105
 
106
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1727
107
  msgid "Cheatin' eh?"
108
  msgstr ""
109
 
110
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1830
111
  msgctxt "Show the media library tab"
112
  msgid "Media Library"
113
  msgstr ""
114
 
115
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1831
116
  msgctxt "Show the support tab"
117
  msgid "Support"
118
  msgstr ""
119
 
120
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:1967
121
  #, php-format
122
  msgid "The file %s has been given %s permissions on Amazon S3."
123
  msgstr ""
124
 
125
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:2427
126
+ msgid "Quick Start Guide"
127
+ msgstr ""
128
+
129
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:2429
130
+ #, php-format
131
+ msgid ""
132
+ "Looks like we don't have write access to this bucket. It's likely that the "
133
+ "user you've provided access keys for hasn't been granted the correct "
134
+ "permissions. Please see our %s for instructions on setting up permissions "
135
+ "correctly."
136
+ msgstr ""
137
+
138
+ #: builds/amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php:2431
139
+ #, php-format
140
+ msgid ""
141
+ "Looks like we don't have access to the buckets. It's likely that the user "
142
+ "you've provided access keys for hasn't been granted the correct permissions. "
143
+ "Please see our %s for instructions on setting up permissions correctly."
144
+ msgstr ""
145
+
146
+ #: builds/amazon-s3-and-cloudfront/classes/as3cf-plugin-compatibility.php:260
147
  #, php-format
148
  msgid "There was an error attempting to download the file %s from S3: %s"
149
  msgstr ""
191
  msgid "Every %d Minutes"
192
  msgstr ""
193
 
194
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:289
195
  msgid "deactivate"
196
  msgstr ""
197
 
198
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:290
199
  #, php-format
200
  msgid "You can %s the %s plugin to get rid of this notice."
201
  msgstr ""
202
 
203
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:293
204
  #, php-format
205
  msgid "%s has been disabled as it requires the %s plugin."
206
  msgstr ""
207
 
208
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:297
209
  msgid "which is currently disabled."
210
  msgstr ""
211
 
212
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:299
213
  msgid "It appears to be installed already."
214
  msgstr ""
215
 
216
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:301
217
  msgctxt "Activate plugin"
218
  msgid "Activate it now."
219
  msgstr ""
220
 
221
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:308
222
  #, php-format
223
  msgid "<a href=\"%s\">Install</a> and activate it."
224
  msgstr ""
225
 
226
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:319
227
  #, php-format
228
  msgid ""
229
  "%s has been disabled as it requires version %s or later of the %s plugin."
230
  msgstr ""
231
 
232
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:322
233
  #, php-format
234
  msgid "You currently have version %s installed."
235
  msgstr ""
236
 
237
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:329
238
  #, php-format
239
  msgid "A valid license for %s is required to update."
240
  msgstr ""
241
 
242
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:337
243
  msgid "Update to the latest version"
244
  msgstr ""
245
 
246
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:349
247
  #, php-format
248
  msgid ""
249
  "%1$s has been disabled because it is not a supported addon of the %2$s "
250
  "plugin."
251
  msgstr ""
252
 
253
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:358
254
  #, php-format
255
  msgid ""
256
  "%1$s has been disabled because it will not work with the version of the %2$s "
257
  "plugin installed. %1$s %3$s or later is required."
258
  msgstr ""
259
 
260
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:361
261
  #, php-format
262
  msgid "Update %s to the latest version"
263
  msgstr ""
264
 
265
+ #: builds/amazon-s3-and-cloudfront/classes/wp-aws-compatibility-check.php:423
266
  #, php-format
267
  msgid "The %s plugin has been deactivated."
268
  msgstr ""
383
  msgid "Access Denied to Bucket"
384
  msgstr ""
385
 
 
 
 
 
 
 
 
 
 
386
  #: builds/amazon-s3-and-cloudfront/view/settings.php:10
387
  msgid "Settings saved."
388
  msgstr ""
518
  msgid "Save Changes"
519
  msgstr ""
520
 
521
+ #: builds/amazon-s3-and-cloudfront/view/sidebar.php:10
522
+ msgid "Upload existing Media Library to S3"
523
  msgstr ""
524
 
525
  #: builds/amazon-s3-and-cloudfront/view/sidebar.php:11
526
+ msgid "Find & replace file URLs in content"
527
+ msgstr ""
528
+
529
+ #: builds/amazon-s3-and-cloudfront/view/sidebar.php:12
530
+ msgid "Manage S3 files in WordPress"
531
+ msgstr ""
532
+
533
+ #: builds/amazon-s3-and-cloudfront/view/sidebar.php:13
534
+ msgid "Assets addon - Serve your CSS & JS from S3/CloudFront"
535
+ msgstr ""
536
+
537
+ #: builds/amazon-s3-and-cloudfront/view/sidebar.php:14
538
+ msgid "WooCommerce addon"
539
  msgstr ""
540
 
541
  #: builds/amazon-s3-and-cloudfront/view/sidebar.php:15
542
+ msgid "Easy Digital Downloads addon"
543
  msgstr ""
544
 
545
  #: builds/amazon-s3-and-cloudfront/view/sidebar.php:16
546
+ msgid "PriorityExpert™ email support"
547
  msgstr ""
548
 
549
+ #: builds/amazon-s3-and-cloudfront/view/sidebar.php:19
550
+ msgid "Visit deliciousbrains.com &rarr;"
 
551
  msgstr ""
552
 
553
+ #: builds/amazon-s3-and-cloudfront/view/sidebar.php:26
554
+ msgid "Get 20% Off!"
555
  msgstr ""
556
 
557
+ #: builds/amazon-s3-and-cloudfront/view/sidebar.php:29
558
+ #, php-format
559
+ msgid ""
560
+ "Submit your name and email and we’ll send you a coupon for 20% off your "
561
+ "upgrade."
562
+ msgstr ""
563
+
564
+ #: builds/amazon-s3-and-cloudfront/view/sidebar.php:33
565
  msgid "Your Email"
566
  msgstr ""
567
 
568
+ #: builds/amazon-s3-and-cloudfront/view/sidebar.php:37
569
  msgid "First Name"
570
  msgstr ""
571
 
572
+ #: builds/amazon-s3-and-cloudfront/view/sidebar.php:41
573
  msgid "Last Name"
574
  msgstr ""
575
 
576
+ #: builds/amazon-s3-and-cloudfront/view/sidebar.php:48
577
+ msgid "Send me the coupon"
578
  msgstr ""
579
 
580
+ #: builds/amazon-s3-and-cloudfront/view/sidebar.php:52
581
  msgid ""
582
  "We promise we will not use your email for anything else and you can "
583
  "unsubscribe with 1-click anytime."
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: bradt
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5VPMGLLK94XJC
4
  Tags: uploads, amazon, s3, mirror, admin, media, cdn, cloudfront
5
  Requires at least: 3.5
6
- Tested up to: 4.2.2
7
- Stable tag: 0.9
8
  License: GPLv3
9
 
10
  Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery.
@@ -59,6 +59,20 @@ This version requires PHP 5.3.3+ and the Amazon Web Services plugin
59
 
60
  == Changelog ==
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  = 0.9 - 2015-07-08 =
63
  * New: Plugin rebranded to WP Offload S3
64
  * New: Support tab added to _Offload S3_ screen containing diagnostic information
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5VPMGLLK94XJC
4
  Tags: uploads, amazon, s3, mirror, admin, media, cdn, cloudfront
5
  Requires at least: 3.5
6
+ Tested up to: 4.3
7
+ Stable tag: 0.9.1
8
  License: GPLv3
9
 
10
  Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery.
59
 
60
  == Changelog ==
61
 
62
+ = 0.9.1 - 2015-07-29- =
63
+ * Improvement: Access denied sample IAM policy replaced with link to [Quick Start Guide](https://deliciousbrains.com/wp-offload-s3/doc/quick-start-guide/)
64
+ * Improvement: Access denied messages on bucket selection or bucket creation now link to [Quick Start Guide](https://deliciousbrains.com/wp-offload-s3/doc/quick-start-guide/)
65
+ * Improvement: Object expires time can now be filtered using the `as3cf_object_meta` filter
66
+ * Bug fix: Error not always shown when S3 bucket inaccessible due to incorrect permissions
67
+ * Bug fix: Permission checks fail when S3 bucket is in a non-default region and defined by `AS3CF_BUCKET` constant
68
+ * Bug fix: Restore `as3cf_get_attached_file_copy_back_to_local` filter
69
+ * Bug fix: Image versions not uploaded to S3 when an edited image is restored
70
+ * Bug fix: Original image version not deleted from server when _Remove Files From Server_ option enabled
71
+ * Bug fix: Media library items with non-ascii characters in the file name are not removed from S3
72
+ * Bug fix: Compatibility notices shown on plugin install pages
73
+ * Bug fix: WordPress footer overlaps WP Offload S3 sidebar
74
+ * Bug fix: Upon initial setup the settings changed alert shows when no settings have changed
75
+
76
  = 0.9 - 2015-07-08 =
77
  * New: Plugin rebranded to WP Offload S3
78
  * New: Support tab added to _Offload S3_ screen containing diagnostic information
uninstall.php CHANGED
@@ -19,9 +19,6 @@ require dirname( __FILE__ ) . '/classes/wp-aws-uninstall.php';
19
  $options = 'tantan_wordpress_s3';
20
  $postmeta = 'amazonS3_info';
21
  $crons = 'as3cf_cron_update_meta_with_region';
22
- $transients = array(
23
- 'as3cf_notices',
24
- 'as3cf_bucket_writable',
25
- );
26
 
27
  $as3cf_uninstall = new WP_AWS_Uninstall( $options, $postmeta, $crons, $transients );
19
  $options = 'tantan_wordpress_s3';
20
  $postmeta = 'amazonS3_info';
21
  $crons = 'as3cf_cron_update_meta_with_region';
22
+ $transients = 'as3cf_notices';
 
 
 
23
 
24
  $as3cf_uninstall = new WP_AWS_Uninstall( $options, $postmeta, $crons, $transients );
view/error-access.php CHANGED
@@ -3,23 +3,6 @@
3
  <strong>
4
  <?php _e( 'Access Denied to Bucket', 'as3cf' ); ?>
5
  </strong>&mdash;
6
- <?php printf( __( 'This could indicate your S3 policy is Read-Only. You need to go to <a href="%s">Identity and Access Management</a> in your AWS console and manage the policy for the user you\'re using for this plugin. Your policy should look something like the following:', 'as3cf' ), 'https://console.aws.amazon.com/iam/home' ); ?>
7
  </p>
8
- <pre><code>{
9
- "Statement": [
10
- {
11
- "Effect": "Allow",
12
- "Action": [
13
- "s3:CreateBucket",
14
- "s3:DeleteObject",
15
- "s3:Put*",
16
- "s3:Get*",
17
- "s3:List*"
18
- ],
19
- "Resource": [
20
- "arn:aws:s3:::*"
21
- ]
22
- }
23
- ]
24
- }</code></pre>
25
  </div>
3
  <strong>
4
  <?php _e( 'Access Denied to Bucket', 'as3cf' ); ?>
5
  </strong>&mdash;
6
+ <?php echo $this->get_access_denied_notice_message(); ?>
7
  </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  </div>
view/sidebar.php CHANGED
@@ -1,23 +1,34 @@
1
  <div class="as3cf-sidebar">
2
 
3
- <div class="as3cf-banner"><img src="<?php echo esc_url( plugins_url( 'assets/img/snail.jpg', $this->plugin_file_path ) ); ?>" width="292" height="165" alt="" /></div>
 
 
4
 
5
- <form method="post" action="https://deliciousbrains.com/email-subscribe/" target="_blank" class="subscribe block">
6
- <h2><?php _e( 'Pro Version?', 'as3cf' ); ?></h2>
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
 
8
  <?php $user = wp_get_current_user(); ?>
9
 
 
 
10
  <p class="intro">
11
- <?php echo wptexturize( __( "We're working on a pro version that will include the following features:", 'as3cf' ) ); // xss ok ?>
12
  </p>
13
 
14
- <ul>
15
- <li><?php echo wptexturize( __( 'Copy existing Media Library to S3', 'as3cf' ) ); // xss ok ?></li>
16
- <li><?php echo wptexturize( __( 'Serve theme JS & CSS from S3/CloudFront', 'as3cf' ) ); // xss ok ?></li>
17
- <li><?php echo wptexturize( __( 'WooCommerce & <abbr title="Easy Digital Downloads">EDD</abbr> integration', 'as3cf' ) ); // xss ok ?></li>
18
- <li><?php echo wptexturize( __( 'Awesome email support', 'as3cf' ) ); // xss ok ?></li>
19
- </ul>
20
-
21
  <div class="field">
22
  <input type="email" name="email" value="<?php echo esc_attr( $user->user_email ); ?>" placeholder="<?php _e( 'Your Email', 'as3cf' ); ?>"/>
23
  </div>
@@ -30,11 +41,11 @@
30
  <input type="text" name="last_name" value="<?php echo esc_attr( trim( $user->last_name ) ); ?>" placeholder="<?php _e( 'Last Name', 'as3cf' ); ?>"/>
31
  </div>
32
 
33
- <input type="hidden" name="campaigns[]" value="3" />
34
  <input type="hidden" name="source" value="1" />
35
 
36
  <div class="field submit-button">
37
- <input type="submit" class="button" value="<?php _e( 'Send me news about a pro version', 'as3cf' ); ?>"/>
38
  </div>
39
 
40
  <p class="promise">
@@ -52,7 +63,7 @@
52
  </a>
53
  </li>
54
  <li>
55
- <a href="https://deliciousbrains.com/?utm_source=insideplugin&utm_medium=web&utm_content=sidebar&utm_campaign=as3cf">
56
  <img src="//www.gravatar.com/avatar/e62fc2e9c8d9fc6edd4fea5339036a91?size=64" alt="" width="32" height="32">
57
  <span>Delicious Brains Inc.</span>
58
  </a>
1
  <div class="as3cf-sidebar">
2
 
3
+ <a class="as3cf-banner" href="https://deliciousbrains.com/wp-offload-s3/?utm_source=insideplugin&amp;utm_medium=web&amp;utm_content=sidebar&amp;utm_campaign=os3-free-plugin">
4
+ <h1>Upgrade</h1>
5
+ </a>
6
 
7
+ <div class="as3cf-upgrade-details">
8
+
9
+ <ul>
10
+ <li><?php echo wptexturize( __( 'Upload existing Media Library to S3', 'as3cf' ) ); // xss ok ?></li>
11
+ <li><?php echo wptexturize( __( 'Find & replace file URLs in content', 'as3cf' ) ); // xss ok ?></li>
12
+ <li><?php echo wptexturize( __( 'Manage S3 files in WordPress', 'as3cf' ) ); // xss ok ?></li>
13
+ <li><?php echo wptexturize( __( 'Assets addon - Serve your CSS & JS from S3/CloudFront', 'as3cf' ) ); // xss ok ?></li>
14
+ <li><?php echo wptexturize( __( 'WooCommerce addon', 'as3cf' ) ); // xss ok ?></li>
15
+ <li><?php echo wptexturize( __( 'Easy Digital Downloads addon', 'as3cf' ) ); // xss ok ?></li>
16
+ <li><?php echo wptexturize( __( 'PriorityExpert™ email support', 'as3cf' ) ); // xss ok ?></li>
17
+ </ul>
18
+
19
+ <p><a href="https://deliciousbrains.com/wp-offload-s3/?utm_source=insideplugin&amp;utm_medium=web&amp;utm_content=sidebar&amp;utm_campaign=os3-free-plugin"><?php echo __( 'Visit deliciousbrains.com &rarr;', 'as3cf' ); ?></a></p>
20
+
21
+ </div>
22
 
23
+ <form method="post" action="https://deliciousbrains.com/email-subscribe/" target="_blank" class="subscribe block">
24
  <?php $user = wp_get_current_user(); ?>
25
 
26
+ <h2><?php _e( 'Get 20% Off!', 'as3cf' ); ?></h2>
27
+
28
  <p class="intro">
29
+ <?php echo wptexturize( __( 'Submit your name and email and we’ll send you a coupon for 20% off your upgrade.', 'as3cf' ) ); // xss ok ?>
30
  </p>
31
 
 
 
 
 
 
 
 
32
  <div class="field">
33
  <input type="email" name="email" value="<?php echo esc_attr( $user->user_email ); ?>" placeholder="<?php _e( 'Your Email', 'as3cf' ); ?>"/>
34
  </div>
41
  <input type="text" name="last_name" value="<?php echo esc_attr( trim( $user->last_name ) ); ?>" placeholder="<?php _e( 'Last Name', 'as3cf' ); ?>"/>
42
  </div>
43
 
44
+ <input type="hidden" name="campaigns[]" value="5" />
45
  <input type="hidden" name="source" value="1" />
46
 
47
  <div class="field submit-button">
48
+ <input type="submit" class="button" value="<?php _e( 'Send me the coupon', 'as3cf' ); ?>"/>
49
  </div>
50
 
51
  <p class="promise">
63
  </a>
64
  </li>
65
  <li>
66
+ <a href="https://deliciousbrains.com/?utm_source=insideplugin&amp;utm_medium=web&amp;utm_content=sidebar&amp;utm_campaign=os3-free-plugin">
67
  <img src="//www.gravatar.com/avatar/e62fc2e9c8d9fc6edd4fea5339036a91?size=64" alt="" width="32" height="32">
68
  <span>Delicious Brains Inc.</span>
69
  </a>
wordpress-s3.php CHANGED
@@ -4,7 +4,7 @@ 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: Brad Touesnard
7
- Version: 0.9
8
  Author URI: http://bradt.ca
9
  Network: True
10
  Text Domain: as3cf
@@ -26,10 +26,10 @@ Domain Path: /languages/
26
  // Then completely rewritten.
27
  */
28
 
29
- $GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['version'] = '0.9';
30
 
31
  $GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['supported_addon_versions'] = array(
32
- 'amazon-s3-and-cloudfront-pro' => '1.0',
33
  );
34
 
35
  $aws_plugin_version_required = '0.3';
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: Brad Touesnard
7
+ Version: 0.9.1
8
  Author URI: http://bradt.ca
9
  Network: True
10
  Text Domain: as3cf
26
  // Then completely rewritten.
27
  */
28
 
29
+ $GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['version'] = '0.9.1';
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';