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