WP Offload S3 Lite - Version 2.5

Version Description

= 2.3 = This is a major upgrade that switches to using a custom table for storing data about offloaded Media Library items. Once upgraded you will not be able to downgrade without restoring data from a backup.

= 2.0 = This is a major upgrade that introduces support for DigitalOcean Spaces, renames the plugin to WP Offload Media Lite, and coincidentally upgrades some of its database settings. You may not be able to downgrade to WP Offload S3 Lite 1.x after upgrading to WP Offload Media Lite 2.0+.

= 1.1 = This is a major change, which ensures S3 URLs are no longer saved in post content. Instead, local URLs are filtered on page generation and replaced with the S3 version. If you depend on the S3 URLs being stored in post content you will need to make modifications to support this version.

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

Download this release

Release Info

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

Code changes from version 2.4.4 to 2.5

README.md CHANGED
@@ -4,7 +4,7 @@
4
  **Requires at least:** 4.9
5
  **Tested up to:** 5.5
6
  **Requires PHP:** 5.5
7
- **Stable tag:** 2.4.4
8
  **License:** GPLv3
9
 
10
  Copies files to Amazon S3, DigitalOcean Spaces or Google Cloud Storage as they are uploaded to the Media Library. Optionally configure Amazon CloudFront or another CDN for faster delivery.
@@ -89,6 +89,13 @@ This version requires PHP 5.3.3+ and the Amazon Web Services plugin
89
 
90
  ## Changelog ##
91
 
 
 
 
 
 
 
 
92
  ### WP Offload Media Lite 2.4.4 - 2020-09-08 ###
93
  * Improvement: Updated AWS PHP SDK to v3.151.6
94
  * Bug fix: Files for duplicate thumbnail sizes not removed from server after initial offload
4
  **Requires at least:** 4.9
5
  **Tested up to:** 5.5
6
  **Requires PHP:** 5.5
7
+ **Stable tag:** 2.5
8
  **License:** GPLv3
9
 
10
  Copies files to Amazon S3, DigitalOcean Spaces or Google Cloud Storage as they are uploaded to the Media Library. Optionally configure Amazon CloudFront or another CDN for faster delivery.
89
 
90
  ## Changelog ##
91
 
92
+ ### WP Offload Media Lite 2.5 - 2020-11-11 ###
93
+ * [Release Summary Blog Post](https://deliciousbrains.com/wp-offload-media-2-5-released/?utm_campaign=changelogs&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting)
94
+ * Improvement: [Error notice shown](https://deliciousbrains.com/wp-offload-media/doc/missing-table-error-notice/?utm_campaign=changelogs&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting) when plugin's required custom table(s) missing
95
+ * Improvement: [Diagnostic Info](https://deliciousbrains.com/wp-offload-media/doc/missing-table-error-notice/?utm_campaign=changelogs&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting#diagnostic-info) shows status of plugin's required custom tables
96
+ * Bug fix: wp_get_original_image_path function does not return provider URL when local files removed
97
+ * Bug fix: File missing notices recorded in debug.log when regenerating thumbnails and Remove Files From Server turned on
98
+
99
  ### WP Offload Media Lite 2.4.4 - 2020-09-08 ###
100
  * Improvement: Updated AWS PHP SDK to v3.151.6
101
  * Bug fix: Files for duplicate thumbnail sizes not removed from server after initial offload
assets/css/attachment.css CHANGED
@@ -1 +1 @@
1
- #s3-actions.postbox .inside{margin:0;padding:0}#s3-actions.postbox a,#s3-actions.postbox a:hover{text-decoration:none}#s3-actions.postbox .s3-details{padding:6px 0}#s3-actions.postbox .s3-details .misc-pub-section{clear:both;float:left;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}#s3-actions.postbox .s3-details .misc-pub-section .s3-key{float:left;width:20%;white-space:nowrap}#s3-actions.postbox .s3-details .misc-pub-section .s3-value{font-weight:bold;float:left;width:80%}#s3-actions.postbox .s3-details .misc-pub-section input.error{color:#a00}#s3-actions.postbox .s3-details .not-copied{color:#666}#s3-actions.postbox .s3-actions{padding:10px;clear:both;border-top:1px solid #ddd;border-bottom:1px solid #ddd;background:#f5f5f5}#s3-actions.postbox .s3-actions .copy-action{text-align:right;float:right;line-height:23px}#s3-actions.postbox .s3-actions .remove-action{line-height:28px;vertical-align:middle;text-align:left;float:left}#s3-actions.postbox .s3-actions .remove-action a.local-warning{color:#a00}#s3-actions.postbox .s3-actions .remove-action a.local-warning:hover{color:#f00}
1
+ #s3-actions.postbox .inside{margin:0;padding:0}#s3-actions.postbox a,#s3-actions.postbox a:hover{text-decoration:none}#s3-actions.postbox .s3-details{padding:6px 0}#s3-actions.postbox .s3-details .misc-pub-section{clear:both;float:left;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}#s3-actions.postbox .s3-details .misc-pub-section .s3-key{float:left;width:20%;white-space:nowrap}#s3-actions.postbox .s3-details .misc-pub-section .s3-value{font-weight:bold;float:left;width:80%}#s3-actions.postbox .s3-details .misc-pub-section .s3-value .more-info{font-weight:lighter}#s3-actions.postbox .s3-details .misc-pub-section input.error{color:#a00}#s3-actions.postbox .s3-details .not-copied{color:#666}#s3-actions.postbox .s3-actions{padding:10px;clear:both;border-top:1px solid #ddd;border-bottom:1px solid #ddd;background:#f5f5f5}#s3-actions.postbox .s3-actions .copy-action{text-align:right;float:right;line-height:23px}#s3-actions.postbox .s3-actions .remove-action{line-height:28px;vertical-align:middle;text-align:left;float:left}#s3-actions.postbox .s3-actions .remove-action a.local-warning{color:#a00}#s3-actions.postbox .s3-actions .remove-action a.local-warning:hover{color:#f00}
assets/js/media.js CHANGED
@@ -63,7 +63,7 @@ var test = {};
63
  return;
64
  }
65
  var $detailsHtml = this.$el.find( '.attachment-info .details' );
66
- var html = this.generateDetails( response, [ 'provider_name', 'region', 'bucket', 'key', 'acl' ] );
67
  $detailsHtml.append( html );
68
  },
69
 
@@ -89,6 +89,16 @@ var test = {};
89
  }
90
  }
91
 
 
 
 
 
 
 
 
 
 
 
92
  html += template( {
93
  key: key,
94
  label: as3cf_media.strings[ key ],
63
  return;
64
  }
65
  var $detailsHtml = this.$el.find( '.attachment-info .details' );
66
+ var html = this.generateDetails( response, [ 'provider_name', 'region', 'bucket', 'key', 'acl', 'is_verified' ] );
67
  $detailsHtml.append( html );
68
  },
69
 
89
  }
90
  }
91
 
92
+ if ( 'is_verified' === key ) {
93
+ value = Boolean( parseInt( value ) );
94
+
95
+ if ( value ) {
96
+ return;
97
+ }
98
+
99
+ value = as3cf_media.strings[ 'not_verified' ];
100
+ }
101
+
102
  html += template( {
103
  key: key,
104
  label: as3cf_media.strings[ key ],
assets/js/media.min.js CHANGED
@@ -1 +1 @@
1
- var test={};!function(a,b){var c=wp.media,d=c.view.Attachment.Details.TwoColumn;c.view.Attachment.Details.TwoColumn=d.extend({events:function(){return b.extend({},d.prototype.events,{"click .local-warning":"confirmS3Removal","click #as3cfpro-toggle-acl":"toggleACL"})},render:function(){this.fetchS3Details(this.model.get("id"))},fetchS3Details:function(a){wp.ajax.send("as3cf_get_attachment_provider_details",{data:{_nonce:as3cf_media.nonces.get_attachment_provider_details,id:a}}).done(b.bind(this.renderView,this))},renderView:function(a){d.prototype.render.apply(this),this.renderActionLinks(a),this.renderS3Details(a)},renderActionLinks:function(c){var d=c&&c.links||[],e=this.$el.find(".actions"),f=a("<div />",{"class":"s3-actions"}),g=[];b(d).each(function(a){g.push(a)}),f.append(g.join(" | ")),e.append(f)},renderS3Details:function(a){if(a&&a.provider_object){var b=this.$el.find(".attachment-info .details"),c=this.generateDetails(a,["provider_name","region","bucket","key","acl"]);b.append(c)}},generateDetails:function(a,c){var d="",e=b.template('<div class="<%= key %>"><strong><%= label %>:</strong> <%= value %></div>');return b(c).each(function(c){if(a.provider_object[c]){var f=a.provider_object[c];if("acl"===c&&(f=a.provider_object[c].name,a.acl_toggle)){var g=b.template('<a href="#" id="as3cfpro-toggle-acl" title="<%= title %>" data-currentACL="<%= acl %>"><%= value %></a>');f=g({title:a.provider_object[c].title,acl:a.provider_object[c].acl,value:f})}d+=e({key:c,label:as3cf_media.strings[c],value:f})}}),d},confirmS3Removal:function(a){if(!confirm(as3cfpro_media.strings.local_warning))return a.preventDefault(),a.stopImmediatePropagation(),!1},toggleACL:function(c){c.preventDefault();var d=a("#as3cfpro-toggle-acl"),e=d.data("currentacl"),f=as3cfpro_media.settings.private_acl;d.hide(),d.after('<span id="as3cfpro-updating">'+as3cfpro_media.strings.updating_acl+"</span>"),e===as3cfpro_media.settings.private_acl&&(f=as3cfpro_media.settings.default_acl),wp.ajax.send("as3cfpro_update_acl",{data:{_ajax_nonce:as3cfpro_media.nonces.singular_update_acl,id:this.model.get("id"),acl:f}}).done(b.bind(this.updateACL,this)).fail(b.bind(this.renderACLError,this))},renderACLError:function(){a("#as3cfpro-updating").remove(),a("#as3cfpro-toggle-acl").show(),alert(as3cfpro_media.strings.change_acl_error)},updateACL:function(b){if(null==b.acl_display||null==b.title||null==b.acl||null==b.url)return void this.renderACLError();this.model.set("url",b.url),this.render();var c=a("#as3cfpro-toggle-acl");a("#as3cfpro-updating").remove(),c.text(b.acl_display),c.attr("title",b.title),c.data("currentacl",b.acl),c.show()}})}(jQuery,_);
1
+ var test={};!function(a,b){var c=wp.media,d=c.view.Attachment.Details.TwoColumn;c.view.Attachment.Details.TwoColumn=d.extend({events:function(){return b.extend({},d.prototype.events,{"click .local-warning":"confirmS3Removal","click #as3cfpro-toggle-acl":"toggleACL"})},render:function(){this.fetchS3Details(this.model.get("id"))},fetchS3Details:function(a){wp.ajax.send("as3cf_get_attachment_provider_details",{data:{_nonce:as3cf_media.nonces.get_attachment_provider_details,id:a}}).done(b.bind(this.renderView,this))},renderView:function(a){d.prototype.render.apply(this),this.renderActionLinks(a),this.renderS3Details(a)},renderActionLinks:function(c){var d=c&&c.links||[],e=this.$el.find(".actions"),f=a("<div />",{"class":"s3-actions"}),g=[];b(d).each(function(a){g.push(a)}),f.append(g.join(" | ")),e.append(f)},renderS3Details:function(a){if(a&&a.provider_object){var b=this.$el.find(".attachment-info .details"),c=this.generateDetails(a,["provider_name","region","bucket","key","acl","is_verified"]);b.append(c)}},generateDetails:function(a,c){var d="",e=b.template('<div class="<%= key %>"><strong><%= label %>:</strong> <%= value %></div>');return b(c).each(function(c){if(a.provider_object[c]){var f=a.provider_object[c];if("acl"===c&&(f=a.provider_object[c].name,a.acl_toggle)){var g=b.template('<a href="#" id="as3cfpro-toggle-acl" title="<%= title %>" data-currentACL="<%= acl %>"><%= value %></a>');f=g({title:a.provider_object[c].title,acl:a.provider_object[c].acl,value:f})}if("is_verified"===c){if(f=Boolean(parseInt(f)))return;f=as3cf_media.strings.not_verified}d+=e({key:c,label:as3cf_media.strings[c],value:f})}}),d},confirmS3Removal:function(a){if(!confirm(as3cfpro_media.strings.local_warning))return a.preventDefault(),a.stopImmediatePropagation(),!1},toggleACL:function(c){c.preventDefault();var d=a("#as3cfpro-toggle-acl"),e=d.data("currentacl"),f=as3cfpro_media.settings.private_acl;d.hide(),d.after('<span id="as3cfpro-updating">'+as3cfpro_media.strings.updating_acl+"</span>"),e===as3cfpro_media.settings.private_acl&&(f=as3cfpro_media.settings.default_acl),wp.ajax.send("as3cfpro_update_acl",{data:{_ajax_nonce:as3cfpro_media.nonces.singular_update_acl,id:this.model.get("id"),acl:f}}).done(b.bind(this.updateACL,this)).fail(b.bind(this.renderACLError,this))},renderACLError:function(){a("#as3cfpro-updating").remove(),a("#as3cfpro-toggle-acl").show(),alert(as3cfpro_media.strings.change_acl_error)},updateACL:function(b){if(null==b.acl_display||null==b.title||null==b.acl||null==b.url)return void this.renderACLError();this.model.set("url",b.url),this.render();var c=a("#as3cfpro-toggle-acl");a("#as3cfpro-updating").remove(),c.text(b.acl_display),c.attr("title",b.title),c.data("currentacl",b.acl),c.show()}})}(jQuery,_);
assets/sass/attachment.scss CHANGED
@@ -3,9 +3,11 @@
3
  margin: 0;
4
  padding: 0;
5
  }
 
6
  a, a:hover {
7
  text-decoration: none;
8
  }
 
9
  .s3-details {
10
  padding: 6px 0;
11
 
@@ -22,19 +24,27 @@
22
  width: 20%;
23
  white-space: nowrap;
24
  }
 
25
  .s3-value {
26
  font-weight: bold;
27
  float: left;
28
  width: 80%;
 
 
 
 
29
  }
 
30
  input.error {
31
  color: #a00;
32
  }
33
  }
 
34
  .not-copied {
35
  color: #666;
36
  }
37
  }
 
38
  .s3-actions {
39
  padding: 10px;
40
  clear: both;
@@ -56,6 +66,7 @@
56
 
57
  a.local-warning {
58
  color: #a00;
 
59
  &:hover {
60
  color: #f00;
61
  }
3
  margin: 0;
4
  padding: 0;
5
  }
6
+
7
  a, a:hover {
8
  text-decoration: none;
9
  }
10
+
11
  .s3-details {
12
  padding: 6px 0;
13
 
24
  width: 20%;
25
  white-space: nowrap;
26
  }
27
+
28
  .s3-value {
29
  font-weight: bold;
30
  float: left;
31
  width: 80%;
32
+
33
+ .more-info {
34
+ font-weight: lighter;
35
+ }
36
  }
37
+
38
  input.error {
39
  color: #a00;
40
  }
41
  }
42
+
43
  .not-copied {
44
  color: #666;
45
  }
46
  }
47
+
48
  .s3-actions {
49
  padding: 10px;
50
  clear: both;
66
 
67
  a.local-warning {
68
  color: #a00;
69
+
70
  &:hover {
71
  color: #f00;
72
  }
classes/amazon-s3-and-cloudfront.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
 
3
  use DeliciousBrains\WP_Offload_Media\Items\Media_Library_Item;
 
4
  use DeliciousBrains\WP_Offload_Media\Providers\Delivery\Another_CDN;
5
  use DeliciousBrains\WP_Offload_Media\Providers\Delivery\AWS_CloudFront;
6
  use DeliciousBrains\WP_Offload_Media\Providers\Delivery\Cloudflare;
@@ -232,6 +233,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
232
  add_filter( 'wp_prepare_attachment_for_js', array( $this, 'maybe_encode_wp_prepare_attachment_for_js', ), 99, 3 );
233
  add_filter( 'image_get_intermediate_size', array( $this, 'maybe_encode_image_get_intermediate_size' ), 99, 3 );
234
  add_filter( 'get_attached_file', array( $this, 'get_attached_file' ), 10, 2 );
 
235
  add_filter( 'wp_audio_shortcode', array( $this, 'wp_media_shortcode' ), 100, 5 );
236
  add_filter( 'wp_video_shortcode', array( $this, 'wp_media_shortcode' ), 100, 5 );
237
 
@@ -1328,6 +1330,13 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1328
  // Checks whether new upload currently has no subsizes recorded but is expected to have subsizes during upload,
1329
  // and if so, are any of its currently missing sizes part of the set.
1330
  if ( ! empty( $data ) && function_exists( 'wp_get_registered_image_subsizes' ) && function_exists( 'wp_get_missing_image_subsizes' ) ) {
 
 
 
 
 
 
 
1331
  if ( empty( $data['sizes'] ) && wp_attachment_is_image( $post_id ) ) {
1332
 
1333
  // There is no unified way of checking whether subsizes are expected, so we have to duplicate WordPress code here.
@@ -2322,14 +2331,15 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2322
  * Get the file prefix
2323
  *
2324
  * @param null|string $time
 
2325
  *
2326
  * @return string
2327
  */
2328
- public function get_file_prefix( $time = null ) {
2329
  $prefix = AS3CF_Utils::trailingslash_prefix( $this->get_object_prefix() );
2330
  $prefix .= AS3CF_Utils::trailingslash_prefix( $this->get_dynamic_prefix( $time ) );
2331
 
2332
- if ( $this->get_setting( 'object-versioning' ) ) {
2333
  $prefix .= AS3CF_Utils::trailingslash_prefix( $this->get_object_version_string() );
2334
  }
2335
 
@@ -2339,19 +2349,20 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2339
  /**
2340
  * Get attachment's new public prefix path for current settings.
2341
  *
2342
- * @param int $post_id Attachment ID
2343
- * @param array $metadata Optional attachment metadata
 
2344
  *
2345
  * @return string
2346
  */
2347
- public function get_new_attachment_prefix( $post_id, $metadata = null ) {
2348
  if ( empty( $metadata ) ) {
2349
  $metadata = wp_get_attachment_metadata( $post_id, true );
2350
  }
2351
 
2352
  $time = $this->get_attachment_folder_year_month( $post_id, $metadata );
2353
 
2354
- return $this->get_file_prefix( $time );
2355
  }
2356
 
2357
  /**
@@ -2459,15 +2470,9 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2459
 
2460
  // Is a signed expiring URL required for the requested object?
2461
  if ( is_null( $expires ) ) {
2462
- if ( is_null( $size ) && $as3cf_item->is_private() ) {
2463
- // Full size URL private
2464
- $expires = self::DEFAULT_EXPIRES;
2465
- }
2466
-
2467
- if ( ! is_null( $size ) && $as3cf_item->is_private_size( $size ) ) {
2468
- // Alternative size URL private
2469
- $expires = self::DEFAULT_EXPIRES;
2470
- }
2471
  }
2472
 
2473
  $item_path = $as3cf_item->path();
@@ -2734,10 +2739,11 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2734
  * @param bool $skip_rewrite_check Still check if offloaded even if not currently rewriting URLs? Default: false
2735
  * @param bool $skip_current_provider_check Skip checking if offloaded to current provider. Default: false, negated if $provider supplied
2736
  * @param Storage_Provider|null $provider Provider where attachment expected to be offloaded to. Default: currently configured provider
 
2737
  *
2738
  * @return bool|Media_Library_Item
2739
  */
2740
- public function is_attachment_served_by_provider( $attachment_id, $skip_rewrite_check = false, $skip_current_provider_check = false, Storage_Provider $provider = null ) {
2741
  if ( ! $skip_rewrite_check && ! $this->get_setting( 'serve-from-s3' ) ) {
2742
  // Not serving provider URLs
2743
  return false;
@@ -2750,6 +2756,11 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2750
  return false;
2751
  }
2752
 
 
 
 
 
 
2753
  if ( ! $skip_current_provider_check && empty( $provider ) ) {
2754
  $provider = $this->get_storage_provider();
2755
  }
@@ -2791,6 +2802,9 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2791
  * unless we know who the calling process is and we are happy
2792
  * to copy the file back to the server to be used.
2793
  *
 
 
 
2794
  * @param string $file
2795
  * @param int $attachment_id
2796
  *
@@ -3404,6 +3418,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3404
  $this->handle_post_request();
3405
  $this->http_prepare_download_log();
3406
  $this->check_for_gd_imagick();
 
3407
 
3408
  do_action( 'as3cf_plugin_load' );
3409
  }
@@ -4127,10 +4142,11 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
4127
  * Make admin notice for when object ACL has changed
4128
  *
4129
  * @param Media_Library_Item $as3cf_item
 
4130
  */
4131
- function make_acl_admin_notice( Media_Library_Item $as3cf_item ) {
4132
- $filename = wp_basename( $as3cf_item->path() );
4133
- $acl = $as3cf_item->is_private() ? $this->get_storage_provider()->get_private_acl() : $this->get_storage_provider()->get_default_acl();
4134
  $acl_name = $this->get_acl_display_name( $acl );
4135
  $text = sprintf( __( '<strong>WP Offload Media</strong> &mdash; The file %s has been given %s permissions in the bucket.', 'amazon-s3-and-cloudfront' ), "<strong>{$filename}</strong>", "<strong>{$acl_name}</strong>" );
4136
 
@@ -4157,6 +4173,44 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
4157
  }
4158
  }
4159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4160
  /**
4161
  * Output image size names and dimensions to a string
4162
  *
@@ -4498,6 +4552,32 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
4498
  $output .= esc_html( $this->get_setting( 'post_meta_version' ) );
4499
  $output .= "\r\n\r\n";
4500
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4501
  $storage_provider = $this->get_storage_provider();
4502
 
4503
  if ( empty( $storage_provider ) ) {
@@ -5064,6 +5144,48 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
5064
  return $attachment_counts;
5065
  }
5066
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5067
  /**
5068
  * Display a notice after either lite or pro plugin has been auto deactivated
5069
  */
@@ -5110,13 +5232,16 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
5110
  /**
5111
  * More info link.
5112
  *
5113
- * @param string $path
5114
- * @param string $utm_content
5115
- * @param string $hash
 
 
 
5116
  *
5117
  * @return string
5118
  */
5119
- public function more_info_link( $path, $utm_content = '', $hash = '' ) {
5120
  $args = array(
5121
  'utm_campaign' => 'support+docs',
5122
  );
@@ -5125,11 +5250,14 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
5125
  $args['utm_content'] = $utm_content;
5126
  }
5127
 
 
 
 
 
5128
  $url = $this->dbrains_url( $path, $args, $hash );
5129
- $text = __( 'More&nbsp;info&nbsp;&raquo;', 'amazon-s3-and-cloudfront' );
5130
  $link = AS3CF_Utils::dbrains_link( $url, $text );
5131
 
5132
- return sprintf( '<span class="more-info">%s</span>', $link );
5133
  }
5134
 
5135
  /**
@@ -5344,6 +5472,10 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
5344
  * @return array|string
5345
  */
5346
  public function get_media_action_strings( $string = null ) {
 
 
 
 
5347
  $strings = apply_filters( 'as3cf_media_action_strings', array(
5348
  'provider' => _x( 'Storage Provider', 'Storage provider key name', 'amazon-s3-and-cloudfront' ),
5349
  'provider_name' => _x( 'Storage Provider', 'Storage provider name', 'amazon-s3-and-cloudfront' ),
@@ -5352,6 +5484,8 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
5352
  'region' => _x( 'Region', 'Location of bucket', 'amazon-s3-and-cloudfront' ),
5353
  'acl' => _x( 'Access', 'Access control list of the file in bucket', 'amazon-s3-and-cloudfront' ),
5354
  'url' => __( 'URL', 'amazon-s3-and-cloudfront' ),
 
 
5355
  ) );
5356
 
5357
  if ( ! is_null( $string ) ) {
1
  <?php
2
 
3
  use DeliciousBrains\WP_Offload_Media\Items\Media_Library_Item;
4
+ use DeliciousBrains\WP_Offload_Media\Items\Item;
5
  use DeliciousBrains\WP_Offload_Media\Providers\Delivery\Another_CDN;
6
  use DeliciousBrains\WP_Offload_Media\Providers\Delivery\AWS_CloudFront;
7
  use DeliciousBrains\WP_Offload_Media\Providers\Delivery\Cloudflare;
233
  add_filter( 'wp_prepare_attachment_for_js', array( $this, 'maybe_encode_wp_prepare_attachment_for_js', ), 99, 3 );
234
  add_filter( 'image_get_intermediate_size', array( $this, 'maybe_encode_image_get_intermediate_size' ), 99, 3 );
235
  add_filter( 'get_attached_file', array( $this, 'get_attached_file' ), 10, 2 );
236
+ add_filter( 'wp_get_original_image_path', array( $this, 'get_attached_file' ), 10, 2 );
237
  add_filter( 'wp_audio_shortcode', array( $this, 'wp_media_shortcode' ), 100, 5 );
238
  add_filter( 'wp_video_shortcode', array( $this, 'wp_media_shortcode' ), 100, 5 );
239
 
1330
  // Checks whether new upload currently has no subsizes recorded but is expected to have subsizes during upload,
1331
  // and if so, are any of its currently missing sizes part of the set.
1332
  if ( ! empty( $data ) && function_exists( 'wp_get_registered_image_subsizes' ) && function_exists( 'wp_get_missing_image_subsizes' ) ) {
1333
+
1334
+ // Plugin compat may require that we wait for wp_generate_attachment_metadata
1335
+ // to be run before proceeding. I.e Regenrerate Thumbnails requires this
1336
+ if ( apply_filters( 'as3cf_wait_for_generate_attachment_metadata', false ) ) {
1337
+ return $data;
1338
+ }
1339
+
1340
  if ( empty( $data['sizes'] ) && wp_attachment_is_image( $post_id ) ) {
1341
 
1342
  // There is no unified way of checking whether subsizes are expected, so we have to duplicate WordPress code here.
2331
  * Get the file prefix
2332
  *
2333
  * @param null|string $time
2334
+ * @param bool $object_versioning_allowed Can an Object Versioning string be appended if setting turned on? Default true.
2335
  *
2336
  * @return string
2337
  */
2338
+ public function get_file_prefix( $time = null, $object_versioning_allowed = true ) {
2339
  $prefix = AS3CF_Utils::trailingslash_prefix( $this->get_object_prefix() );
2340
  $prefix .= AS3CF_Utils::trailingslash_prefix( $this->get_dynamic_prefix( $time ) );
2341
 
2342
+ if ( ! empty( $object_versioning_allowed ) && $this->get_setting( 'object-versioning' ) ) {
2343
  $prefix .= AS3CF_Utils::trailingslash_prefix( $this->get_object_version_string() );
2344
  }
2345
 
2349
  /**
2350
  * Get attachment's new public prefix path for current settings.
2351
  *
2352
+ * @param int $post_id Attachment ID
2353
+ * @param array $metadata Optional attachment metadata
2354
+ * @param bool $object_versioning_allowed Can an Object Versioning string be appended if setting turned on? Default true.
2355
  *
2356
  * @return string
2357
  */
2358
+ public function get_new_attachment_prefix( $post_id, $metadata = null, $object_versioning_allowed = true ) {
2359
  if ( empty( $metadata ) ) {
2360
  $metadata = wp_get_attachment_metadata( $post_id, true );
2361
  }
2362
 
2363
  $time = $this->get_attachment_folder_year_month( $post_id, $metadata );
2364
 
2365
+ return $this->get_file_prefix( $time, $object_versioning_allowed );
2366
  }
2367
 
2368
  /**
2470
 
2471
  // Is a signed expiring URL required for the requested object?
2472
  if ( is_null( $expires ) ) {
2473
+ $expires = $as3cf_item->is_private_size( $size ) ? self::DEFAULT_EXPIRES : null;
2474
+ } else {
2475
+ $expires = $as3cf_item->is_private_size( $size ) ? $expires : null;
 
 
 
 
 
 
2476
  }
2477
 
2478
  $item_path = $as3cf_item->path();
2739
  * @param bool $skip_rewrite_check Still check if offloaded even if not currently rewriting URLs? Default: false
2740
  * @param bool $skip_current_provider_check Skip checking if offloaded to current provider. Default: false, negated if $provider supplied
2741
  * @param Storage_Provider|null $provider Provider where attachment expected to be offloaded to. Default: currently configured provider
2742
+ * @param bool $check_is_verified Check that metadata is verified, has no effect if $skip_rewrite_check is true. Default: false
2743
  *
2744
  * @return bool|Media_Library_Item
2745
  */
2746
+ public function is_attachment_served_by_provider( $attachment_id, $skip_rewrite_check = false, $skip_current_provider_check = false, Storage_Provider $provider = null, $check_is_verified = false ) {
2747
  if ( ! $skip_rewrite_check && ! $this->get_setting( 'serve-from-s3' ) ) {
2748
  // Not serving provider URLs
2749
  return false;
2756
  return false;
2757
  }
2758
 
2759
+ if ( ! $skip_rewrite_check && ! empty( $check_is_verified ) && ! $as3cf_item->is_verified() ) {
2760
+ // Offload not verified, treat as not offloaded.
2761
+ return false;
2762
+ }
2763
+
2764
  if ( ! $skip_current_provider_check && empty( $provider ) ) {
2765
  $provider = $this->get_storage_provider();
2766
  }
2802
  * unless we know who the calling process is and we are happy
2803
  * to copy the file back to the server to be used.
2804
  *
2805
+ * @handles get_attached_file
2806
+ * @handles wp_get_original_image_path
2807
+ *
2808
  * @param string $file
2809
  * @param int $attachment_id
2810
  *
3418
  $this->handle_post_request();
3419
  $this->http_prepare_download_log();
3420
  $this->check_for_gd_imagick();
3421
+ $this->check_for_items_table();
3422
 
3423
  do_action( 'as3cf_plugin_load' );
3424
  }
4142
  * Make admin notice for when object ACL has changed
4143
  *
4144
  * @param Media_Library_Item $as3cf_item
4145
+ * @param string|null $size
4146
  */
4147
+ function make_acl_admin_notice( Media_Library_Item $as3cf_item, $size = null ) {
4148
+ $filename = wp_basename( $as3cf_item->path( $size ) );
4149
+ $acl = $as3cf_item->is_private_size( $size ) ? $this->get_storage_provider()->get_private_acl() : $this->get_storage_provider()->get_default_acl();
4150
  $acl_name = $this->get_acl_display_name( $acl );
4151
  $text = sprintf( __( '<strong>WP Offload Media</strong> &mdash; The file %s has been given %s permissions in the bucket.', 'amazon-s3-and-cloudfront' ), "<strong>{$filename}</strong>", "<strong>{$acl_name}</strong>" );
4152
 
4173
  }
4174
  }
4175
 
4176
+ /**
4177
+ * Ensure items table(s) exists in the database
4178
+ */
4179
+ private function check_for_items_table() {
4180
+ if ( ! $this->is_plugin_setup( true ) ) {
4181
+ // No notice until plugin is setup
4182
+ return;
4183
+ }
4184
+
4185
+ if ( is_multisite() && ! is_network_admin() ) {
4186
+ return;
4187
+ }
4188
+
4189
+ $missing_tables = $this->get_db_init_status( false );
4190
+
4191
+ if ( count( $missing_tables ) !== 0 ) {
4192
+ $this->notices->add_notice(
4193
+ sprintf(
4194
+ __( '<strong>Missing Table</strong> &mdash; One or more required database tables are missing, please check the Diagnostic Info in the Support tab for details. %s', 'amazon-s3-and-cloudfront' ),
4195
+ $this->more_info_link(
4196
+ '/wp-offload-media/doc/missing-table-error-notice',
4197
+ 'missing-table'
4198
+ )
4199
+ ),
4200
+ array(
4201
+ 'custom_id' => 'items_table_error',
4202
+ 'type' => 'error',
4203
+ 'dismissible' => false,
4204
+ 'flash' => false,
4205
+ 'only_show_to_user' => false,
4206
+ 'only_show_in_settings' => true,
4207
+ )
4208
+ );
4209
+ } else {
4210
+ $this->notices->remove_notice_by_id( 'items_table_error' );
4211
+ }
4212
+ }
4213
+
4214
  /**
4215
  * Output image size names and dimensions to a string
4216
  *
4552
  $output .= esc_html( $this->get_setting( 'post_meta_version' ) );
4553
  $output .= "\r\n\r\n";
4554
 
4555
+ /*
4556
+ * Items db tables status
4557
+ */
4558
+
4559
+ $db_init_statuses = $this->get_db_init_status( true );
4560
+ $missing_tables = $this->get_db_init_status( false );
4561
+
4562
+ $output .= "Custom tables:\r\n";
4563
+ if ( count( $missing_tables ) === 0 ) {
4564
+ $output .= $db_init_statuses[1]['name'] . ': Ok';
4565
+ $output .= "\r\n";
4566
+ } else {
4567
+ // Output the first 5 missing tables
4568
+ $table_count = 0;
4569
+ foreach ( $missing_tables as $missing_table ) {
4570
+ $table_count++;
4571
+ if ( $table_count > 5 ) {
4572
+ break;
4573
+ }
4574
+ $output .= $missing_table['name'] . ': ';
4575
+ $output .= $missing_table['status'] ? 'Ok' : 'Missing';
4576
+ $output .= "\r\n";
4577
+ }
4578
+ }
4579
+ $output .= "\r\n";
4580
+
4581
  $storage_provider = $this->get_storage_provider();
4582
 
4583
  if ( empty( $storage_provider ) ) {
5144
  return $attachment_counts;
5145
  }
5146
 
5147
+ /**
5148
+ * Check the existence of the items table (as3cf_items). Returns an array with one row per
5149
+ * possible database prefix (multisite support).
5150
+ *
5151
+ * @param bool $all Return all tables or just missing tables. Defaults to all/true.
5152
+ * @param bool $skip_transient Whether to force database query and skip transient, default false.
5153
+ *
5154
+ * @return array
5155
+ */
5156
+ private function get_db_init_status( $all = true, $skip_transient = false ) {
5157
+ global $wpdb;
5158
+
5159
+ if ( $skip_transient || false === ( $db_init_status = get_site_transient( 'as3cf_db_init_status' ) ) ) {
5160
+ $table_prefixes = $this->get_all_blog_table_prefixes();
5161
+
5162
+ $db_init_status = array();
5163
+
5164
+ foreach ( $table_prefixes as $blog_id => $table_prefix ) {
5165
+ $table_name = $table_prefix . Item::ITEMS_TABLE;
5166
+
5167
+ $db_init_status[ $blog_id ] = array(
5168
+ 'name' => $table_name,
5169
+ 'status' => false,
5170
+ );
5171
+
5172
+ if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name ) {
5173
+ $db_init_status[ $blog_id ]['status'] = true;
5174
+ }
5175
+ }
5176
+
5177
+ set_site_transient( 'as3cf_db_init_status', $db_init_status, 5 * MINUTE_IN_SECONDS );
5178
+ }
5179
+
5180
+ if ( ! $all ) {
5181
+ $db_init_status = array_filter( $db_init_status, function ( $table ) {
5182
+ return false === $table['status'];
5183
+ } );
5184
+ }
5185
+
5186
+ return $db_init_status;
5187
+ }
5188
+
5189
  /**
5190
  * Display a notice after either lite or pro plugin has been auto deactivated
5191
  */
5232
  /**
5233
  * More info link.
5234
  *
5235
+ * @param string $path Relative path on DBI site
5236
+ * @param string $utm_content Optional utm_content value.
5237
+ * @param string $hash Optional hash anchor value without the '#'.
5238
+ * @param string $text Optional override of link text.
5239
+ * @param string $prefix Optional non-linked prefix text.
5240
+ * @param string $suffix Optional non-linked suffix text.
5241
  *
5242
  * @return string
5243
  */
5244
+ public function more_info_link( $path, $utm_content = '', $hash = '', $text = '', $prefix = '', $suffix = '' ) {
5245
  $args = array(
5246
  'utm_campaign' => 'support+docs',
5247
  );
5250
  $args['utm_content'] = $utm_content;
5251
  }
5252
 
5253
+ $text = empty( $text ) ? __( 'More&nbsp;info&nbsp;&raquo;', 'amazon-s3-and-cloudfront' ) : $text;
5254
+ $prefix = empty( $prefix ) ? '' : $prefix;
5255
+ $suffix = empty( $suffix ) ? '' : $suffix;
5256
+
5257
  $url = $this->dbrains_url( $path, $args, $hash );
 
5258
  $link = AS3CF_Utils::dbrains_link( $url, $text );
5259
 
5260
+ return sprintf( '<span class="more-info">%s%s%s</span>', $prefix, $link, $suffix );
5261
  }
5262
 
5263
  /**
5472
  * @return array|string
5473
  */
5474
  public function get_media_action_strings( $string = null ) {
5475
+ $not_verified_value = __( 'No', 'amazon-s3-and-cloudfront' );
5476
+ $not_verified_value .= '&nbsp;';
5477
+ $not_verified_value .= $this->more_info_link( '/wp-offload-media/doc/add-metadata-tool/', 'os3+attachment+metabox', 'analyze-and-repair', 'More Info', '(', ')' );
5478
+
5479
  $strings = apply_filters( 'as3cf_media_action_strings', array(
5480
  'provider' => _x( 'Storage Provider', 'Storage provider key name', 'amazon-s3-and-cloudfront' ),
5481
  'provider_name' => _x( 'Storage Provider', 'Storage provider name', 'amazon-s3-and-cloudfront' ),
5484
  'region' => _x( 'Region', 'Location of bucket', 'amazon-s3-and-cloudfront' ),
5485
  'acl' => _x( 'Access', 'Access control list of the file in bucket', 'amazon-s3-and-cloudfront' ),
5486
  'url' => __( 'URL', 'amazon-s3-and-cloudfront' ),
5487
+ 'is_verified' => _x( 'Verified', 'Whether or not metadata has been verified', 'amazon-s3-and-cloudfront' ),
5488
+ 'not_verified' => $not_verified_value,
5489
  ) );
5490
 
5491
  if ( ! is_null( $string ) ) {
classes/as3cf-filter.php CHANGED
@@ -582,7 +582,7 @@ abstract class AS3CF_Filter {
582
  *
583
  * @return null|string
584
  */
585
- protected function get_size_string_from_url( $attachment_id, $url ) {
586
  $meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
587
 
588
  if ( empty( $meta['sizes'] ) ) {
@@ -848,8 +848,8 @@ abstract class AS3CF_Filter {
848
  *
849
  * @return string
850
  */
851
- protected function remove_aws_query_strings( $content, $base_url = '' ) {
852
- $pattern = '\?[^\s"<\?]*(?:X-Amz-Algorithm|AWSAccessKeyId)=[^\s"<\?]+';
853
  $group = 0;
854
 
855
  if ( ! is_string( $content ) ) {
582
  *
583
  * @return null|string
584
  */
585
+ public function get_size_string_from_url( $attachment_id, $url ) {
586
  $meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
587
 
588
  if ( empty( $meta['sizes'] ) ) {
848
  *
849
  * @return string
850
  */
851
+ public static function remove_aws_query_strings( $content, $base_url = '' ) {
852
+ $pattern = '\?[^\s"<\?]*(?:X-Amz-Algorithm|AWSAccessKeyId|Key-Pair-Id)=[^\s"<\?]+';
853
  $group = 0;
854
 
855
  if ( ! is_string( $content ) ) {
classes/as3cf-plugin-compatibility.php CHANGED
@@ -46,6 +46,16 @@ class AS3CF_Plugin_Compatibility {
46
  */
47
  private $removed_files = array();
48
 
 
 
 
 
 
 
 
 
 
 
49
  /**
50
  * @param Amazon_S3_And_CloudFront $as3cf
51
  */
@@ -118,6 +128,7 @@ class AS3CF_Plugin_Compatibility {
118
  * Regenerate Thumbnails v3+ and other REST-API using plugins that need a local file.
119
  */
120
  add_filter( 'rest_dispatch_request', array( $this, 'rest_dispatch_request_copy_back_to_local' ), 10, 4 );
 
121
 
122
  /*
123
  * WP-CLI Compatibility
@@ -171,6 +182,8 @@ class AS3CF_Plugin_Compatibility {
171
  $this,
172
  'prevent_copy_back_to_local_after_remove',
173
  ), 10, 4 );
 
 
174
  }
175
 
176
  /**
@@ -219,6 +232,37 @@ class AS3CF_Plugin_Compatibility {
219
  return false;
220
  }
221
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  /**
223
  * Check the current request is a specific one based on action and
224
  * optional context
@@ -983,6 +1027,8 @@ class AS3CF_Plugin_Compatibility {
983
  foreach ( $routes as $match_route ) {
984
  if ( preg_match( '@' . $match_route . '@i', $route ) ) {
985
  $this->enable_get_attached_file_copy_back_to_local();
 
 
986
  break;
987
  }
988
  }
46
  */
47
  private $removed_files = array();
48
 
49
+ /**
50
+ * @var bool
51
+ */
52
+ protected $generate_attachment_metadata_done = false;
53
+
54
+ /**
55
+ * @var bool
56
+ */
57
+ protected $wait_for_generate_attachment_metadata = false;
58
+
59
  /**
60
  * @param Amazon_S3_And_CloudFront $as3cf
61
  */
128
  * Regenerate Thumbnails v3+ and other REST-API using plugins that need a local file.
129
  */
130
  add_filter( 'rest_dispatch_request', array( $this, 'rest_dispatch_request_copy_back_to_local' ), 10, 4 );
131
+ add_filter( 'as3cf_wait_for_generate_attachment_metadata', array( $this, 'wait_for_generate_attachment_metadata' ) );
132
 
133
  /*
134
  * WP-CLI Compatibility
182
  $this,
183
  'prevent_copy_back_to_local_after_remove',
184
  ), 10, 4 );
185
+
186
+ add_filter( 'wp_generate_attachment_metadata', array( $this, 'wp_generate_attachment_metadata' ) );
187
  }
188
 
189
  /**
232
  return false;
233
  }
234
 
235
+ /**
236
+ * Handler for wp_generate_attachment_metadata. Updates class
237
+ * member variable when the filter has fired.
238
+ *
239
+ * @handles wp_generate_attachment_metadata
240
+ *
241
+ * @param $metadata
242
+ *
243
+ * @return mixed
244
+ */
245
+ public function wp_generate_attachment_metadata( $metadata ) {
246
+ $this->generate_attachment_metadata_done = true;
247
+ return $metadata;
248
+ }
249
+
250
+ /**
251
+ * Are we waiting for the wp_generate_attachment_metadata filter and
252
+ * if so, has it run yet?
253
+ *
254
+ * @handles as3cf_wait_for_generate_attachment_metadata
255
+ *
256
+ * @return bool
257
+ */
258
+ public function wait_for_generate_attachment_metadata() {
259
+ if ( ! $this->wait_for_generate_attachment_metadata ) {
260
+ return false;
261
+ }
262
+
263
+ return ! $this->generate_attachment_metadata_done;
264
+ }
265
+
266
  /**
267
  * Check the current request is a specific one based on action and
268
  * optional context
1027
  foreach ( $routes as $match_route ) {
1028
  if ( preg_match( '@' . $match_route . '@i', $route ) ) {
1029
  $this->enable_get_attached_file_copy_back_to_local();
1030
+ $this->wait_for_generate_attachment_metadata = true;
1031
+ $this->generate_attachment_metadata_done = false;
1032
  break;
1033
  }
1034
  }
classes/as3cf-utils.php CHANGED
@@ -111,6 +111,21 @@ if ( ! class_exists( 'AS3CF_Utils' ) ) {
111
  return $url;
112
  }
113
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  /**
115
  * Reduce the given URL down to the simplest version of itself.
116
  *
111
  return $url;
112
  }
113
 
114
+ /**
115
+ * Is the given size recognized as the full sized image?
116
+ *
117
+ * @param string|null $size
118
+ *
119
+ * @return bool
120
+ */
121
+ public static function is_full_size( $size ) {
122
+ if ( empty( $size ) || in_array( $size, array( 'full', 'original' ) ) ) {
123
+ return true;
124
+ }
125
+
126
+ return false;
127
+ }
128
+
129
  /**
130
  * Reduce the given URL down to the simplest version of itself.
131
  *
classes/filters/as3cf-local-to-s3.php CHANGED
@@ -202,7 +202,7 @@ class AS3CF_Local_To_S3 extends AS3CF_Filter {
202
  *
203
  * @return bool|int
204
  */
205
- protected function get_attachment_id_from_url( $url ) {
206
  $results = $this->get_attachment_ids_from_urls( array( $url ) );
207
 
208
  if ( empty( $results ) ) {
202
  *
203
  * @return bool|int
204
  */
205
+ public function get_attachment_id_from_url( $url ) {
206
  $results = $this->get_attachment_ids_from_urls( array( $url ) );
207
 
208
  if ( empty( $results ) ) {
classes/items/item.php CHANGED
@@ -8,6 +8,10 @@ use WP_Error;
8
 
9
  abstract class Item {
10
  const ITEMS_TABLE = 'as3cf_items';
 
 
 
 
11
 
12
  protected static $source_type = 'media-library';
13
  protected static $source_table = 'posts';
@@ -41,6 +45,8 @@ abstract class Item {
41
  private $source_path;
42
  private $original_source_path;
43
  private $extra_info;
 
 
44
 
45
  /**
46
  * Item constructor.
@@ -54,9 +60,24 @@ abstract class Item {
54
  * @param string $source_path Path that source uses, could be relative or absolute depending on source.
55
  * @param string $original_filename An optional filename with no path that was previously used for the item.
56
  * @param array $extra_info An optional array of extra data specific to the source type.
57
- * @param null $id Optional Item record ID.
 
 
58
  */
59
- public function __construct( $provider, $region, $bucket, $path, $is_private, $source_id, $source_path, $original_filename = null, $extra_info = array(), $id = null ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  $this->provider = $provider;
61
  $this->region = $region;
62
  $this->bucket = $bucket;
@@ -65,6 +86,8 @@ abstract class Item {
65
  $this->source_id = $source_id;
66
  $this->source_path = $source_path;
67
  $this->extra_info = serialize( $extra_info );
 
 
68
 
69
  if ( empty( $original_filename ) ) {
70
  $this->original_path = $path;
@@ -394,7 +417,7 @@ abstract class Item {
394
 
395
  $sql = "
396
  CREATE TABLE {$table_name} (
397
- id BIGINT(20) NOT NULL AUTO_INCREMENT,
398
  provider VARCHAR(18) NOT NULL,
399
  region VARCHAR(255) NOT NULL,
400
  bucket VARCHAR(255) NOT NULL,
@@ -402,17 +425,20 @@ abstract class Item {
402
  original_path VARCHAR(1024) NOT NULL,
403
  is_private BOOLEAN NOT NULL DEFAULT 0,
404
  source_type VARCHAR(18) NOT NULL,
405
- source_id BIGINT(20) NOT NULL,
406
  source_path VARCHAR(1024) NOT NULL,
407
  original_source_path VARCHAR(1024) NOT NULL,
408
  extra_info LONGTEXT,
 
 
409
  PRIMARY KEY (id),
410
  UNIQUE KEY uidx_path (path(190), id),
411
  UNIQUE KEY uidx_original_path (original_path(190), id),
412
  UNIQUE KEY uidx_source_path (source_path(190), id),
413
  UNIQUE KEY uidx_original_source_path (original_source_path(190), id),
414
  UNIQUE KEY uidx_source (source_type, source_id),
415
- UNIQUE KEY uidx_provider_bucket (provider, bucket(190), id)
 
416
  ) $charset_collate;
417
  ";
418
  dbDelta( $sql );
@@ -438,6 +464,8 @@ abstract class Item {
438
  'source_path' => $this->source_path,
439
  'original_source_path' => $this->original_source_path,
440
  'extra_info' => $this->extra_info,
 
 
441
  );
442
 
443
  if ( $include_id && ! empty( $this->id ) ) {
@@ -491,6 +519,8 @@ abstract class Item {
491
  'source_path' => '%s',
492
  'original_source_path' => '%s',
493
  'extra_info' => '%s',
 
 
494
  );
495
 
496
  if ( $include_id && ! empty( $this->id ) ) {
@@ -600,7 +630,9 @@ abstract class Item {
600
  $object->source_path,
601
  wp_basename( $object->original_source_path ),
602
  $extra_info,
603
- $object->id
 
 
604
  );
605
 
606
  if ( $add_to_object_cache ) {
@@ -743,6 +775,15 @@ abstract class Item {
743
  return (bool) $this->is_private;
744
  }
745
 
 
 
 
 
 
 
 
 
 
746
  /**
747
  * Getter for item's source_id value.
748
  *
@@ -779,6 +820,42 @@ abstract class Item {
779
  return unserialize( $this->extra_info );
780
  }
781
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
782
  /**
783
  * Get normalized object path dir.
784
  *
@@ -890,7 +967,7 @@ abstract class Item {
890
  }
891
 
892
  // Regardless of whether 1 or many items found, must validate match.
893
- $path = ltrim( $parts['path'], '/' );
894
 
895
  foreach ( $results as $result ) {
896
  $as3cf_item = static::create( $result );
@@ -924,10 +1001,12 @@ abstract class Item {
924
  * @param integer $upper_bound Returned source_ids should be lower than this, use null/0 for no upper bound.
925
  * @param integer $limit Maximum number of source_ids to return. Required if not counting.
926
  * @param bool $count Just return a count of matching source_ids? Negates $limit, default false.
 
 
927
  *
928
  * @return array|int
929
  */
930
- public static function get_source_ids( $upper_bound, $limit, $count = false ) {
931
  global $wpdb;
932
 
933
  $args = array( static::$source_type );
@@ -945,6 +1024,30 @@ abstract class Item {
945
  $args[] = $upper_bound;
946
  }
947
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
948
  if ( ! $count ) {
949
  $sql .= ' ORDER BY source_id DESC LIMIT %d';
950
  $args[] = $limit;
8
 
9
  abstract class Item {
10
  const ITEMS_TABLE = 'as3cf_items';
11
+ const ORIGINATORS = array(
12
+ 'standard' => 0,
13
+ 'metadata-tool' => 1,
14
+ );
15
 
16
  protected static $source_type = 'media-library';
17
  protected static $source_table = 'posts';
45
  private $source_path;
46
  private $original_source_path;
47
  private $extra_info;
48
+ private $originator;
49
+ private $is_verified;
50
 
51
  /**
52
  * Item constructor.
60
  * @param string $source_path Path that source uses, could be relative or absolute depending on source.
61
  * @param string $original_filename An optional filename with no path that was previously used for the item.
62
  * @param array $extra_info An optional array of extra data specific to the source type.
63
+ * @param int $id Optional Item record ID.
64
+ * @param int $originator Optional originator of record from ORIGINATORS const.
65
+ * @param bool $is_verified Optional flag as to whether Item's objects are known to exist.
66
  */
67
+ public function __construct(
68
+ $provider,
69
+ $region,
70
+ $bucket,
71
+ $path,
72
+ $is_private,
73
+ $source_id,
74
+ $source_path,
75
+ $original_filename = null,
76
+ $extra_info = array(),
77
+ $id = null,
78
+ $originator = 0,
79
+ $is_verified = true
80
+ ) {
81
  $this->provider = $provider;
82
  $this->region = $region;
83
  $this->bucket = $bucket;
86
  $this->source_id = $source_id;
87
  $this->source_path = $source_path;
88
  $this->extra_info = serialize( $extra_info );
89
+ $this->originator = $originator;
90
+ $this->is_verified = $is_verified;
91
 
92
  if ( empty( $original_filename ) ) {
93
  $this->original_path = $path;
417
 
418
  $sql = "
419
  CREATE TABLE {$table_name} (
420
+ id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
421
  provider VARCHAR(18) NOT NULL,
422
  region VARCHAR(255) NOT NULL,
423
  bucket VARCHAR(255) NOT NULL,
425
  original_path VARCHAR(1024) NOT NULL,
426
  is_private BOOLEAN NOT NULL DEFAULT 0,
427
  source_type VARCHAR(18) NOT NULL,
428
+ source_id BIGINT(20) UNSIGNED NOT NULL,
429
  source_path VARCHAR(1024) NOT NULL,
430
  original_source_path VARCHAR(1024) NOT NULL,
431
  extra_info LONGTEXT,
432
+ originator TINYINT UNSIGNED NOT NULL DEFAULT 0,
433
+ is_verified BOOLEAN NOT NULL DEFAULT 1,
434
  PRIMARY KEY (id),
435
  UNIQUE KEY uidx_path (path(190), id),
436
  UNIQUE KEY uidx_original_path (original_path(190), id),
437
  UNIQUE KEY uidx_source_path (source_path(190), id),
438
  UNIQUE KEY uidx_original_source_path (original_source_path(190), id),
439
  UNIQUE KEY uidx_source (source_type, source_id),
440
+ UNIQUE KEY uidx_provider_bucket (provider, bucket(190), id),
441
+ UNIQUE KEY uidx_is_verified_originator (is_verified, originator, id)
442
  ) $charset_collate;
443
  ";
444
  dbDelta( $sql );
464
  'source_path' => $this->source_path,
465
  'original_source_path' => $this->original_source_path,
466
  'extra_info' => $this->extra_info,
467
+ 'originator' => $this->originator,
468
+ 'is_verified' => $this->is_verified,
469
  );
470
 
471
  if ( $include_id && ! empty( $this->id ) ) {
519
  'source_path' => '%s',
520
  'original_source_path' => '%s',
521
  'extra_info' => '%s',
522
+ 'originator' => '%d',
523
+ 'is_verified' => '%d',
524
  );
525
 
526
  if ( $include_id && ! empty( $this->id ) ) {
630
  $object->source_path,
631
  wp_basename( $object->original_source_path ),
632
  $extra_info,
633
+ $object->id,
634
+ $object->originator,
635
+ $object->is_verified
636
  );
637
 
638
  if ( $add_to_object_cache ) {
775
  return (bool) $this->is_private;
776
  }
777
 
778
+ /**
779
+ * Setter for item's is_private value
780
+ *
781
+ * @param bool $private
782
+ */
783
+ public function set_is_private( $private ) {
784
+ $this->is_private = (bool) $private;
785
+ }
786
+
787
  /**
788
  * Getter for item's source_id value.
789
  *
820
  return unserialize( $this->extra_info );
821
  }
822
 
823
+ /**
824
+ * Setter for extra_info value
825
+ *
826
+ * @param array $extra_info
827
+ */
828
+ protected function set_extra_info( $extra_info ) {
829
+ $this->extra_info = serialize( $extra_info );
830
+ }
831
+
832
+ /**
833
+ * Getter for item's originator value.
834
+ *
835
+ * @return integer
836
+ */
837
+ public function originator() {
838
+ return $this->originator;
839
+ }
840
+
841
+ /**
842
+ * Getter for item's is_verified value.
843
+ *
844
+ * @return bool
845
+ */
846
+ public function is_verified() {
847
+ return (bool) $this->is_verified;
848
+ }
849
+
850
+ /**
851
+ * Setter for item's is_verified value
852
+ *
853
+ * @param bool $is_verified
854
+ */
855
+ public function set_is_verified( $is_verified ) {
856
+ $this->is_verified = (bool) $is_verified;
857
+ }
858
+
859
  /**
860
  * Get normalized object path dir.
861
  *
967
  }
968
 
969
  // Regardless of whether 1 or many items found, must validate match.
970
+ $path = AS3CF_Utils::decode_filename_in_path( ltrim( $parts['path'], '/' ) );
971
 
972
  foreach ( $results as $result ) {
973
  $as3cf_item = static::create( $result );
1001
  * @param integer $upper_bound Returned source_ids should be lower than this, use null/0 for no upper bound.
1002
  * @param integer $limit Maximum number of source_ids to return. Required if not counting.
1003
  * @param bool $count Just return a count of matching source_ids? Negates $limit, default false.
1004
+ * @param int $originator Optionally restrict to only records with given originator type from ORIGINATORS const.
1005
+ * @param bool $is_verified Optionally restrict to only records that either are or are not verified.
1006
  *
1007
  * @return array|int
1008
  */
1009
+ public static function get_source_ids( $upper_bound, $limit, $count = false, $originator = null, $is_verified = null ) {
1010
  global $wpdb;
1011
 
1012
  $args = array( static::$source_type );
1024
  $args[] = $upper_bound;
1025
  }
1026
 
1027
+ // If an originator type given, check that it is valid before continuing and using.
1028
+ if ( null !== $originator ) {
1029
+ if ( is_int( $originator ) && in_array( $originator, self::ORIGINATORS ) ) {
1030
+ $sql .= ' AND originator = %d';
1031
+ $args[] = $originator;
1032
+ } else {
1033
+ \AS3CF_Error::log( __METHOD__ . ' called with invalid originator: ' . $originator );
1034
+
1035
+ return $count ? 0 : array();
1036
+ }
1037
+ }
1038
+
1039
+ // If an is_verified value given, check that it is valid before continuing and using.
1040
+ if ( null !== $is_verified ) {
1041
+ if ( is_bool( $is_verified ) ) {
1042
+ $sql .= ' AND is_verified = %d';
1043
+ $args[] = (int) $is_verified;
1044
+ } else {
1045
+ \AS3CF_Error::log( __METHOD__ . ' called with invalid is_verified: ' . $is_verified );
1046
+
1047
+ return $count ? 0 : array();
1048
+ }
1049
+ }
1050
+
1051
  if ( ! $count ) {
1052
  $sql .= ' ORDER BY source_id DESC LIMIT %d';
1053
  $args[] = $limit;
classes/items/media-library-item.php CHANGED
@@ -27,9 +27,24 @@ class Media_Library_Item extends Item {
27
  * 'private_prefix' => 'private/'
28
  * For backwards compatibility, if a simple array is supplied it is treated as
29
  * private thumbnail sizes that should be private objects in the bucket.
30
- * @param null $id Optional Item record ID.
 
 
31
  */
32
- public function __construct( $provider, $region, $bucket, $path, $is_private, $source_id, $source_path, $original_filename = null, $extra_info = array(), $id = null ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  // For Media Library items, the source path should be relative to the Media Library's uploads directory.
34
  $uploads = wp_upload_dir();
35
 
@@ -60,7 +75,130 @@ class Media_Library_Item extends Item {
60
  'private_prefix' => $private_prefix,
61
  );
62
 
63
- parent::__construct( $provider, $region, $bucket, $path, $is_private, $source_id, $source_path, $original_filename, $extra_info, $id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  }
65
 
66
  /**
@@ -141,6 +279,28 @@ class Media_Library_Item extends Item {
141
  return $paths;
142
  }
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  /**
145
  * Get the array of thumbnail sizes that are private in the bucket.
146
  *
@@ -165,6 +325,30 @@ class Media_Library_Item extends Item {
165
  return array();
166
  }
167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  /**
169
  * Get the private status for a specific size.
170
  *
@@ -173,7 +357,7 @@ class Media_Library_Item extends Item {
173
  * @return bool
174
  */
175
  public function is_private_size( $size ) {
176
- if ( empty( $size ) || in_array( $size, array( 'full', 'original' ) ) ) {
177
  return $this->is_private();
178
  }
179
 
27
  * 'private_prefix' => 'private/'
28
  * For backwards compatibility, if a simple array is supplied it is treated as
29
  * private thumbnail sizes that should be private objects in the bucket.
30
+ * @param int $id Optional Item record ID.
31
+ * @param int $originator Optional originator of record from ORIGINATORS const.
32
+ * @param bool $is_verified Optional flag as to whether Item's objects are known to exist.
33
  */
34
+ public function __construct(
35
+ $provider,
36
+ $region,
37
+ $bucket,
38
+ $path,
39
+ $is_private,
40
+ $source_id,
41
+ $source_path,
42
+ $original_filename = null,
43
+ $extra_info = array(),
44
+ $id = null,
45
+ $originator = 0,
46
+ $is_verified = true
47
+ ) {
48
  // For Media Library items, the source path should be relative to the Media Library's uploads directory.
49
  $uploads = wp_upload_dir();
50
 
75
  'private_prefix' => $private_prefix,
76
  );
77
 
78
+ parent::__construct( $provider, $region, $bucket, $path, $is_private, $source_id, $source_path, $original_filename, $extra_info, $id, $originator, $is_verified );
79
+ }
80
+
81
+ /**
82
+ * Get a new Media_Library_Item with all data derived from attachment data and current settings.
83
+ *
84
+ * @param int $attachment_id Attachment ID to construct record from.
85
+ * @param bool $object_versioning_allowed Can an Object Versioning string be appended if setting turned on? Default true.
86
+ * @param int $originator Originator of new record. Optional, default standard (0).
87
+ *
88
+ * @return Media_Library_Item|WP_Error
89
+ */
90
+ public static function create_from_attachment( $attachment_id, $object_versioning_allowed = true, $originator = 0 ) {
91
+ /** @var Amazon_S3_And_CloudFront $as3cf */
92
+ global $as3cf;
93
+
94
+ if ( empty( $attachment_id ) ) {
95
+ return new WP_Error(
96
+ 'exception',
97
+ __( 'Empty Attachment ID passed to ' . __FUNCTION__, 'amazon-s3-and-cloudfront' )
98
+ );
99
+ }
100
+
101
+ $object_versioning_allowed = empty( $object_versioning_allowed ) ? false : true;
102
+
103
+ if ( ! in_array( $originator, self::ORIGINATORS ) ) {
104
+ return new WP_Error(
105
+ 'exception',
106
+ __( 'Invalid Originator passed to ' . __FUNCTION__, 'amazon-s3-and-cloudfront' )
107
+ );
108
+ }
109
+
110
+ // If we ever expand originators to include more pre-verified versions, this will need changing.
111
+ $is_verified = 0 === $originator;
112
+
113
+ /*
114
+ * Provider basics.
115
+ */
116
+
117
+ $provider = $as3cf->get_storage_provider()->get_provider_key_name();
118
+ $region = $as3cf->get_setting( 'region' );
119
+ if ( is_wp_error( $region ) ) {
120
+ $region = '';
121
+ }
122
+ $bucket = $as3cf->get_setting( 'bucket' );
123
+
124
+ /*
125
+ * Derive local and remote paths.
126
+ */
127
+
128
+ // Verify that get_attached_file will not blow up as it does not check the data it manipulates.
129
+ $attached_file_meta = get_post_meta( $attachment_id, '_wp_attached_file', true );
130
+ if ( ! is_string( $attached_file_meta ) ) {
131
+ return new WP_Error(
132
+ 'exception',
133
+ sprintf( __( 'Media Library item with ID %d has damaged meta data', 'amazon-s3-and-cloudfront' ), $attachment_id )
134
+ );
135
+ }
136
+ unset( $attached_file_meta );
137
+
138
+ $source_path = get_attached_file( $attachment_id, true );
139
+
140
+ // Check for valid "full" file path otherwise we'll not be able to create offload path or download in the future.
141
+ if ( empty( $source_path ) ) {
142
+ return new WP_Error(
143
+ 'exception',
144
+ sprintf( __( 'Media Library item with ID %d does not have a valid file path', 'amazon-s3-and-cloudfront' ), $attachment_id )
145
+ );
146
+ }
147
+
148
+ $attachment_metadata = wp_get_attachment_metadata( $attachment_id, true );
149
+
150
+ if ( is_wp_error( $attachment_metadata ) ) {
151
+ return $attachment_metadata;
152
+ }
153
+
154
+ $prefix = $as3cf->get_new_attachment_prefix( $attachment_id, $attachment_metadata, $object_versioning_allowed );
155
+ $path = $prefix . wp_basename( $source_path );
156
+
157
+ // There may be an original image that can override the default original filename.
158
+ $original_filename = empty( $attachment_metadata['original_image'] ) ? null : $attachment_metadata['original_image'];
159
+
160
+ /*
161
+ * Private file handling.
162
+ */
163
+
164
+ $acl = apply_filters( 'as3cf_upload_acl', $as3cf->get_storage_provider()->get_default_acl(), $attachment_metadata, $attachment_id );
165
+ $is_private = ! empty( $acl ) && $as3cf->get_storage_provider()->get_private_acl() === $acl;
166
+
167
+ // Maybe set private sizes and private prefix.
168
+ $extra_info = array(
169
+ 'private_sizes' => array(),
170
+ 'private_prefix' => '',
171
+ );
172
+
173
+ $file_paths = AS3CF_Utils::get_attachment_file_paths( $attachment_id, false, $attachment_metadata );
174
+ $file_paths = array_diff( $file_paths, array( $source_path ) );
175
+
176
+ foreach ( $file_paths as $size => $size_file_path ) {
177
+ $acl = apply_filters( 'as3cf_upload_acl_sizes', $as3cf->get_storage_provider()->get_default_acl(), $size, $attachment_id, $attachment_metadata );
178
+
179
+ if ( ! empty( $acl ) && $as3cf->get_storage_provider()->get_private_acl() === $acl ) {
180
+ $extra_info['private_sizes'][] = $size;
181
+ }
182
+ }
183
+
184
+ if ( $as3cf->private_prefix_enabled() ) {
185
+ $extra_info['private_prefix'] = AS3CF_Utils::trailingslash_prefix( $as3cf->get_setting( 'signed-urls-object-prefix', '' ) );
186
+ }
187
+
188
+ return new self(
189
+ $provider,
190
+ $region,
191
+ $bucket,
192
+ $path,
193
+ $is_private,
194
+ $attachment_id,
195
+ $source_path,
196
+ $original_filename,
197
+ $extra_info,
198
+ null,
199
+ $originator,
200
+ $is_verified
201
+ );
202
  }
203
 
204
  /**
279
  return $paths;
280
  }
281
 
282
+ /**
283
+ * Getter for item's path value, optionally for a specific size
284
+ *
285
+ * @param null|string $size
286
+ *
287
+ * @return string
288
+ */
289
+ public function path( $size = null ) {
290
+ $path = parent::path();
291
+
292
+ if ( empty( $size ) ) {
293
+ return $path;
294
+ }
295
+
296
+ $meta = get_post_meta( $this->source_id(), '_wp_attachment_metadata', true );
297
+ if ( ! empty( $meta['sizes'][ $size ]['file'] ) ) {
298
+ $path = str_replace( wp_basename( $path ), $meta['sizes'][ $size ]['file'], $path );
299
+ }
300
+
301
+ return $path;
302
+ }
303
+
304
  /**
305
  * Get the array of thumbnail sizes that are private in the bucket.
306
  *
325
  return array();
326
  }
327
 
328
+ /**
329
+ * Set the private status for a specific size.
330
+ *
331
+ * @param $size
332
+ * @param $private
333
+ */
334
+ public function set_private_size( $size, $private ) {
335
+ if ( empty( $size ) || AS3CF_Utils::is_full_size( $size ) ) {
336
+ return;
337
+ }
338
+
339
+ $extra_info = $this->extra_info();
340
+ $private_sizes = $this->private_sizes();
341
+ if ( $private && ! in_array( $size, $private_sizes, true ) ) {
342
+ $private_sizes[] = $size;
343
+ }
344
+ if ( ! $private && in_array( $size, $private_sizes, true ) ) {
345
+ $private_sizes = array_diff( $private_sizes, array( $size ) );
346
+ }
347
+ $extra_info['private_sizes'] = $private_sizes;
348
+
349
+ $this->set_extra_info( $extra_info );
350
+ }
351
+
352
  /**
353
  * Get the private status for a specific size.
354
  *
357
  * @return bool
358
  */
359
  public function is_private_size( $size ) {
360
+ if ( AS3CF_Utils::is_full_size( $size ) ) {
361
  return $this->is_private();
362
  }
363
 
languages/amazon-s3-and-cloudfront-en.pot CHANGED
@@ -8,7 +8,7 @@ msgid ""
8
  msgstr ""
9
  "Project-Id-Version: amazon-s3-and-cloudfront\n"
10
  "Report-Msgid-Bugs-To: nom@deliciousbrains.com\n"
11
- "POT-Creation-Date: 2020-09-08 12:17+0100\n"
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,17 +17,17 @@ msgstr ""
17
  "Content-Type: text/plain; charset=UTF-8\n"
18
  "Content-Transfer-Encoding: 8bit\n"
19
 
20
- #: classes/amazon-s3-and-cloudfront.php:165
21
  #: classes/amazon-s3-and-cloudfront.php:166
 
22
  msgid "Offload Media Lite"
23
  msgstr ""
24
 
25
- #: classes/amazon-s3-and-cloudfront.php:400
26
- #: classes/amazon-s3-and-cloudfront.php:417
27
  msgid "Unknown"
28
  msgstr ""
29
 
30
- #: classes/amazon-s3-and-cloudfront.php:489
31
  #: view/bucket-select.php:87
32
  #: view/delivery-provider-select.php:129
33
  #: view/delivery-provider-select.php:149
@@ -38,221 +38,223 @@ msgstr ""
38
  msgid "defined in wp-config.php"
39
  msgstr ""
40
 
41
- #: classes/amazon-s3-and-cloudfront.php:1413
42
  #, php-format
43
  msgid "Media Library item ID %d. Provided path is not a string"
44
  msgstr ""
45
 
46
- #: classes/amazon-s3-and-cloudfront.php:1421
 
47
  #, php-format
48
  msgid "Media Library item with ID %d has damaged meta data"
49
  msgstr ""
50
 
51
- #: classes/amazon-s3-and-cloudfront.php:1432
 
52
  #, php-format
53
  msgid "Media Library item with ID %d does not have a valid file path"
54
  msgstr ""
55
 
56
- #: classes/amazon-s3-and-cloudfront.php:1483
57
- #: classes/amazon-s3-and-cloudfront.php:1708
58
  #, php-format
59
  msgid "File %s does not exist"
60
  msgstr ""
61
 
62
- #: classes/amazon-s3-and-cloudfront.php:1512
63
  #, php-format
64
  msgid "Mime type %s is not allowed"
65
  msgstr ""
66
 
67
- #: classes/amazon-s3-and-cloudfront.php:1523
68
  msgid "Already offloaded to a different provider"
69
  msgstr ""
70
 
71
- #: classes/amazon-s3-and-cloudfront.php:1631
72
- #: classes/amazon-s3-and-cloudfront.php:1722
73
  #, php-format
74
  msgid "Error offloading %s to provider: %s"
75
  msgstr ""
76
 
77
- #: classes/amazon-s3-and-cloudfront.php:2840
78
  msgid "This action can only be performed through an admin screen."
79
  msgstr ""
80
 
81
- #: classes/amazon-s3-and-cloudfront.php:2842
82
  msgid "Cheatin&#8217; eh?"
83
  msgstr ""
84
 
85
- #: classes/amazon-s3-and-cloudfront.php:2844
86
  msgid "You do not have sufficient permissions to access this page."
87
  msgstr ""
88
 
89
- #: classes/amazon-s3-and-cloudfront.php:3168
90
  msgid "Error Getting Bucket Region"
91
  msgstr ""
92
 
93
- #: classes/amazon-s3-and-cloudfront.php:3169
94
  #, php-format
95
  msgid "There was an error attempting to get the region of the bucket %s: %s"
96
  msgstr ""
97
 
98
- #: classes/amazon-s3-and-cloudfront.php:3272
99
  msgid ""
100
  "This is a test file to check if the user has write permission to the bucket. "
101
  "Delete me if found."
102
  msgstr ""
103
 
104
- #: classes/amazon-s3-and-cloudfront.php:3278
105
  #, php-format
106
  msgid ""
107
  "There was an error attempting to check the permissions of the bucket %s: %s"
108
  msgstr ""
109
 
110
- #: classes/amazon-s3-and-cloudfront.php:3374
111
  msgid "Error creating bucket"
112
  msgstr ""
113
 
114
- #: classes/amazon-s3-and-cloudfront.php:3375
115
  msgid "Bucket name too short."
116
  msgstr ""
117
 
118
- #: classes/amazon-s3-and-cloudfront.php:3376
119
  msgid "Bucket name too long."
120
  msgstr ""
121
 
122
- #: classes/amazon-s3-and-cloudfront.php:3377
123
  msgid ""
124
  "Invalid character. Bucket names can contain lowercase letters, numbers, "
125
  "periods and hyphens."
126
  msgstr ""
127
 
128
- #: classes/amazon-s3-and-cloudfront.php:3378
129
  msgid "Error saving bucket"
130
  msgstr ""
131
 
132
- #: classes/amazon-s3-and-cloudfront.php:3379
133
  msgid "Error fetching buckets"
134
  msgstr ""
135
 
136
- #: classes/amazon-s3-and-cloudfront.php:3380
137
  msgid "Error getting URL preview: "
138
  msgstr ""
139
 
140
- #: classes/amazon-s3-and-cloudfront.php:3381
141
  msgid "The changes you made will be lost if you navigate away from this page"
142
  msgstr ""
143
 
144
- #: classes/amazon-s3-and-cloudfront.php:3382
145
  msgid "Getting diagnostic info..."
146
  msgstr ""
147
 
148
- #: classes/amazon-s3-and-cloudfront.php:3383
149
  msgid "Error getting diagnostic info: "
150
  msgstr ""
151
 
152
- #: classes/amazon-s3-and-cloudfront.php:3384
153
  msgctxt "placeholder for hidden access key, 39 char max"
154
  msgid "-- not shown --"
155
  msgstr ""
156
 
157
- #: classes/amazon-s3-and-cloudfront.php:3386
158
- #: classes/amazon-s3-and-cloudfront.php:5643
159
  msgid "Settings saved."
160
  msgstr ""
161
 
162
- #: classes/amazon-s3-and-cloudfront.php:3507
163
  msgid "Cheatin' eh?"
164
  msgstr ""
165
 
166
- #: classes/amazon-s3-and-cloudfront.php:3580
167
  #, php-format
168
  msgid "Could not set new Delivery Provider: %s"
169
  msgstr ""
170
 
171
- #: classes/amazon-s3-and-cloudfront.php:3655
172
- #: classes/amazon-s3-and-cloudfront.php:3785
173
  msgid "No bucket name provided."
174
  msgstr ""
175
 
176
- #: classes/amazon-s3-and-cloudfront.php:3664
177
  msgid "Bucket name not valid."
178
  msgstr ""
179
 
180
- #: classes/amazon-s3-and-cloudfront.php:3677
181
  msgid "No region provided."
182
  msgstr ""
183
 
184
- #: classes/amazon-s3-and-cloudfront.php:3754
185
  #, php-format
186
  msgctxt "Trying to change public access setting for given provider's bucket."
187
  msgid "Can't change Block All Public Access setting for %s buckets."
188
  msgstr ""
189
 
190
- #: classes/amazon-s3-and-cloudfront.php:3763
191
  msgid "No block public access setting provided."
192
  msgstr ""
193
 
194
- #: classes/amazon-s3-and-cloudfront.php:3776
195
  msgid "Storage Provider not configured with access credentials."
196
  msgstr ""
197
 
198
- #: classes/amazon-s3-and-cloudfront.php:3803
199
  msgid "Could not change Block All Public Access status for bucket."
200
  msgstr ""
201
 
202
- #: classes/amazon-s3-and-cloudfront.php:3820
203
  msgid ""
204
  "<strong>Failed to Enable Block All Public Access</strong> &mdash; We could "
205
  "not enable Block All Public Access. You will need to log in to the AWS "
206
  "Console and do it manually."
207
  msgstr ""
208
 
209
- #: classes/amazon-s3-and-cloudfront.php:3822
210
  msgid ""
211
  "<strong>Failed to Disable Block All Public Access</strong> &mdash; We could "
212
  "not disable Block All Public Access. You will need to log in to the AWS "
213
  "Console and do it manually."
214
  msgstr ""
215
 
216
- #: classes/amazon-s3-and-cloudfront.php:3857
217
  #: view/provider-select.php:329
218
  msgctxt "placeholder for hidden secret access key, 39 char max"
219
  msgid "-- not shown --"
220
  msgstr ""
221
 
222
- #: classes/amazon-s3-and-cloudfront.php:3880
223
  msgid "Key File not valid JSON."
224
  msgstr ""
225
 
226
- #: classes/amazon-s3-and-cloudfront.php:3892
227
- #: classes/amazon-s3-and-cloudfront.php:3906
228
- #: classes/amazon-s3-and-cloudfront.php:3915
229
  msgctxt "missing form field"
230
  msgid " not provided."
231
  msgstr ""
232
 
233
- #: classes/amazon-s3-and-cloudfront.php:3958
234
  msgctxt "Show the media library tab"
235
  msgid "Media Library"
236
  msgstr ""
237
 
238
- #: classes/amazon-s3-and-cloudfront.php:3959
239
  msgctxt "Show the addons tab"
240
  msgid "Addons"
241
  msgstr ""
242
 
243
- #: classes/amazon-s3-and-cloudfront.php:3960
244
  msgctxt "Show the support tab"
245
  msgid "Support"
246
  msgstr ""
247
 
248
- #: classes/amazon-s3-and-cloudfront.php:4135
249
  #, php-format
250
  msgid ""
251
  "<strong>WP Offload Media</strong> &mdash; The file %s has been given %s "
252
  "permissions in the bucket."
253
  msgstr ""
254
 
255
- #: classes/amazon-s3-and-cloudfront.php:4154
256
  msgid ""
257
  "<strong>WP Offload Media Requirement Missing</strong> &mdash; Looks like you "
258
  "don't have an image manipulation library installed on this server and "
@@ -260,18 +262,26 @@ msgid ""
260
  "Please setup GD or ImageMagick."
261
  msgstr ""
262
 
263
- #: classes/amazon-s3-and-cloudfront.php:4936
 
 
 
 
 
 
 
 
264
  #, php-format
265
  msgid ""
266
  "<a href=\"%s\">Define your access keys</a> to enable write access to the "
267
  "bucket"
268
  msgstr ""
269
 
270
- #: classes/amazon-s3-and-cloudfront.php:4943
271
  msgid "Quick Start Guide"
272
  msgstr ""
273
 
274
- #: classes/amazon-s3-and-cloudfront.php:4945
275
  #, php-format
276
  msgid ""
277
  "Looks like we don't have write access to this bucket. It's likely that the "
@@ -280,7 +290,7 @@ msgid ""
280
  "correctly."
281
  msgstr ""
282
 
283
- #: classes/amazon-s3-and-cloudfront.php:4947
284
  #, php-format
285
  msgid ""
286
  "Looks like we don't have access to the buckets. It's likely that the user "
@@ -288,39 +298,39 @@ msgid ""
288
  "Please see our %s for instructions on setting up permissions correctly."
289
  msgstr ""
290
 
291
- #: classes/amazon-s3-and-cloudfront.php:5073
292
  msgid "WP Offload Media Activation"
293
  msgstr ""
294
 
295
- #: classes/amazon-s3-and-cloudfront.php:5074
296
  msgid ""
297
  "WP Offload Media Lite and WP Offload Media cannot both be active. We've "
298
  "automatically deactivated WP Offload Media Lite."
299
  msgstr ""
300
 
301
- #: classes/amazon-s3-and-cloudfront.php:5076
302
  msgid "WP Offload Media Lite Activation"
303
  msgstr ""
304
 
305
- #: classes/amazon-s3-and-cloudfront.php:5077
306
  msgid ""
307
  "WP Offload Media Lite and WP Offload Media cannot both be active. We've "
308
  "automatically deactivated WP Offload Media."
309
  msgstr ""
310
 
311
- #: classes/amazon-s3-and-cloudfront.php:5129
312
  msgid "More&nbsp;info&nbsp;&raquo;"
313
  msgstr ""
314
 
315
- #: classes/amazon-s3-and-cloudfront.php:5205
316
  msgid "this doc"
317
  msgstr ""
318
 
319
- #: classes/amazon-s3-and-cloudfront.php:5207
320
  msgid "WP Offload Media Feature Removed"
321
  msgstr ""
322
 
323
- #: classes/amazon-s3-and-cloudfront.php:5208
324
  #, php-format
325
  msgid ""
326
  "You had the \"Always non-SSL\" option selected in your settings, but we've "
@@ -331,59 +341,68 @@ msgid ""
331
  "to the old behavior."
332
  msgstr ""
333
 
334
- #: classes/amazon-s3-and-cloudfront.php:5243
335
  msgid "Offload"
336
  msgstr ""
337
 
338
- #: classes/amazon-s3-and-cloudfront.php:5348
 
 
 
 
339
  msgctxt "Storage provider key name"
340
  msgid "Storage Provider"
341
  msgstr ""
342
 
343
- #: classes/amazon-s3-and-cloudfront.php:5349
344
  msgctxt "Storage provider name"
345
  msgid "Storage Provider"
346
  msgstr ""
347
 
348
- #: classes/amazon-s3-and-cloudfront.php:5350
349
  msgctxt "Bucket name"
350
  msgid "Bucket"
351
  msgstr ""
352
 
353
- #: classes/amazon-s3-and-cloudfront.php:5351
354
  msgctxt "Path to file in bucket"
355
  msgid "Path"
356
  msgstr ""
357
 
358
- #: classes/amazon-s3-and-cloudfront.php:5352
359
  msgctxt "Location of bucket"
360
  msgid "Region"
361
  msgstr ""
362
 
363
- #: classes/amazon-s3-and-cloudfront.php:5353
364
  msgctxt "Access control list of the file in bucket"
365
  msgid "Access"
366
  msgstr ""
367
 
368
- #: classes/amazon-s3-and-cloudfront.php:5354
369
  msgid "URL"
370
  msgstr ""
371
 
372
- #: classes/amazon-s3-and-cloudfront.php:5606
 
 
 
 
 
373
  msgid "Assets Pull"
374
  msgstr ""
375
 
376
- #: classes/amazon-s3-and-cloudfront.php:5607
377
  msgid ""
378
  "An addon for WP Offload Media to serve your site's JS, CSS, and other "
379
  "enqueued assets from Amazon CloudFront or another CDN."
380
  msgstr ""
381
 
382
- #: classes/amazon-s3-and-cloudfront.php:5611
383
  msgid "Feature"
384
  msgstr ""
385
 
386
- #: classes/amazon-s3-and-cloudfront.php:5657
387
  #, php-format
388
  msgid ""
389
  "<strong>Amazon Web Services Plugin No Longer Required</strong> &mdash; As of "
@@ -394,7 +413,7 @@ msgid ""
394
  "plugin, it should be safe to deactivate and delete it. %2$s"
395
  msgstr ""
396
 
397
- #: classes/amazon-s3-and-cloudfront.php:5689
398
  #, php-format
399
  msgid ""
400
  "<strong>WP Offload Media Settings Moved</strong> &mdash; You now define your "
@@ -527,26 +546,34 @@ msgstr ""
527
  msgid "Settings"
528
  msgstr ""
529
 
530
- #: classes/as3cf-plugin-compatibility.php:595
531
  #, php-format
532
  msgid "The local directory %s does not exist and could not be created."
533
  msgstr ""
534
 
535
- #: classes/as3cf-plugin-compatibility.php:596
536
- #: classes/as3cf-plugin-compatibility.php:608
537
  #: classes/upgrades/upgrade-meta-wp-error.php:81
538
  #, php-format
539
  msgid ""
540
  "There was an error attempting to download the file %s from the bucket: %s"
541
  msgstr ""
542
 
543
- #: classes/as3cf-plugin-compatibility.php:933
544
  #, php-format
545
  msgid ""
546
  "<strong>Warning:</strong> This site is using PHP %1$s, in a future update WP "
547
  "Offload Media will require PHP %2$s or later. %3$s"
548
  msgstr ""
549
 
 
 
 
 
 
 
 
 
550
  #: classes/providers/delivery/another-cdn.php:47
551
  #: classes/providers/delivery/digitalocean-spaces-cdn.php:83
552
  msgid "Fast, No Private Media"
@@ -764,11 +791,11 @@ msgstr ""
764
  msgid "This item has not been offloaded yet."
765
  msgstr ""
766
 
767
- #: view/attachment-metabox.php:49
768
  msgid "File does not exist on server"
769
  msgstr ""
770
 
771
- #: view/attachment-metabox.php:57
772
  msgid "File exists on server"
773
  msgstr ""
774
 
8
  msgstr ""
9
  "Project-Id-Version: amazon-s3-and-cloudfront\n"
10
  "Report-Msgid-Bugs-To: nom@deliciousbrains.com\n"
11
+ "POT-Creation-Date: 2020-11-11 11:45+0000\n"
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
17
  "Content-Type: text/plain; charset=UTF-8\n"
18
  "Content-Transfer-Encoding: 8bit\n"
19
 
 
20
  #: classes/amazon-s3-and-cloudfront.php:166
21
+ #: classes/amazon-s3-and-cloudfront.php:167
22
  msgid "Offload Media Lite"
23
  msgstr ""
24
 
25
+ #: classes/amazon-s3-and-cloudfront.php:402
26
+ #: classes/amazon-s3-and-cloudfront.php:419
27
  msgid "Unknown"
28
  msgstr ""
29
 
30
+ #: classes/amazon-s3-and-cloudfront.php:491
31
  #: view/bucket-select.php:87
32
  #: view/delivery-provider-select.php:129
33
  #: view/delivery-provider-select.php:149
38
  msgid "defined in wp-config.php"
39
  msgstr ""
40
 
41
+ #: classes/amazon-s3-and-cloudfront.php:1422
42
  #, php-format
43
  msgid "Media Library item ID %d. Provided path is not a string"
44
  msgstr ""
45
 
46
+ #: classes/amazon-s3-and-cloudfront.php:1430
47
+ #: classes/items/media-library-item.php:133
48
  #, php-format
49
  msgid "Media Library item with ID %d has damaged meta data"
50
  msgstr ""
51
 
52
+ #: classes/amazon-s3-and-cloudfront.php:1441
53
+ #: classes/items/media-library-item.php:144
54
  #, php-format
55
  msgid "Media Library item with ID %d does not have a valid file path"
56
  msgstr ""
57
 
58
+ #: classes/amazon-s3-and-cloudfront.php:1492
59
+ #: classes/amazon-s3-and-cloudfront.php:1717
60
  #, php-format
61
  msgid "File %s does not exist"
62
  msgstr ""
63
 
64
+ #: classes/amazon-s3-and-cloudfront.php:1521
65
  #, php-format
66
  msgid "Mime type %s is not allowed"
67
  msgstr ""
68
 
69
+ #: classes/amazon-s3-and-cloudfront.php:1532
70
  msgid "Already offloaded to a different provider"
71
  msgstr ""
72
 
73
+ #: classes/amazon-s3-and-cloudfront.php:1640
74
+ #: classes/amazon-s3-and-cloudfront.php:1731
75
  #, php-format
76
  msgid "Error offloading %s to provider: %s"
77
  msgstr ""
78
 
79
+ #: classes/amazon-s3-and-cloudfront.php:2854
80
  msgid "This action can only be performed through an admin screen."
81
  msgstr ""
82
 
83
+ #: classes/amazon-s3-and-cloudfront.php:2856
84
  msgid "Cheatin&#8217; eh?"
85
  msgstr ""
86
 
87
+ #: classes/amazon-s3-and-cloudfront.php:2858
88
  msgid "You do not have sufficient permissions to access this page."
89
  msgstr ""
90
 
91
+ #: classes/amazon-s3-and-cloudfront.php:3182
92
  msgid "Error Getting Bucket Region"
93
  msgstr ""
94
 
95
+ #: classes/amazon-s3-and-cloudfront.php:3183
96
  #, php-format
97
  msgid "There was an error attempting to get the region of the bucket %s: %s"
98
  msgstr ""
99
 
100
+ #: classes/amazon-s3-and-cloudfront.php:3286
101
  msgid ""
102
  "This is a test file to check if the user has write permission to the bucket. "
103
  "Delete me if found."
104
  msgstr ""
105
 
106
+ #: classes/amazon-s3-and-cloudfront.php:3292
107
  #, php-format
108
  msgid ""
109
  "There was an error attempting to check the permissions of the bucket %s: %s"
110
  msgstr ""
111
 
112
+ #: classes/amazon-s3-and-cloudfront.php:3388
113
  msgid "Error creating bucket"
114
  msgstr ""
115
 
116
+ #: classes/amazon-s3-and-cloudfront.php:3389
117
  msgid "Bucket name too short."
118
  msgstr ""
119
 
120
+ #: classes/amazon-s3-and-cloudfront.php:3390
121
  msgid "Bucket name too long."
122
  msgstr ""
123
 
124
+ #: classes/amazon-s3-and-cloudfront.php:3391
125
  msgid ""
126
  "Invalid character. Bucket names can contain lowercase letters, numbers, "
127
  "periods and hyphens."
128
  msgstr ""
129
 
130
+ #: classes/amazon-s3-and-cloudfront.php:3392
131
  msgid "Error saving bucket"
132
  msgstr ""
133
 
134
+ #: classes/amazon-s3-and-cloudfront.php:3393
135
  msgid "Error fetching buckets"
136
  msgstr ""
137
 
138
+ #: classes/amazon-s3-and-cloudfront.php:3394
139
  msgid "Error getting URL preview: "
140
  msgstr ""
141
 
142
+ #: classes/amazon-s3-and-cloudfront.php:3395
143
  msgid "The changes you made will be lost if you navigate away from this page"
144
  msgstr ""
145
 
146
+ #: classes/amazon-s3-and-cloudfront.php:3396
147
  msgid "Getting diagnostic info..."
148
  msgstr ""
149
 
150
+ #: classes/amazon-s3-and-cloudfront.php:3397
151
  msgid "Error getting diagnostic info: "
152
  msgstr ""
153
 
154
+ #: classes/amazon-s3-and-cloudfront.php:3398
155
  msgctxt "placeholder for hidden access key, 39 char max"
156
  msgid "-- not shown --"
157
  msgstr ""
158
 
159
+ #: classes/amazon-s3-and-cloudfront.php:3400
160
+ #: classes/amazon-s3-and-cloudfront.php:5777
161
  msgid "Settings saved."
162
  msgstr ""
163
 
164
+ #: classes/amazon-s3-and-cloudfront.php:3522
165
  msgid "Cheatin' eh?"
166
  msgstr ""
167
 
168
+ #: classes/amazon-s3-and-cloudfront.php:3595
169
  #, php-format
170
  msgid "Could not set new Delivery Provider: %s"
171
  msgstr ""
172
 
173
+ #: classes/amazon-s3-and-cloudfront.php:3670
174
+ #: classes/amazon-s3-and-cloudfront.php:3800
175
  msgid "No bucket name provided."
176
  msgstr ""
177
 
178
+ #: classes/amazon-s3-and-cloudfront.php:3679
179
  msgid "Bucket name not valid."
180
  msgstr ""
181
 
182
+ #: classes/amazon-s3-and-cloudfront.php:3692
183
  msgid "No region provided."
184
  msgstr ""
185
 
186
+ #: classes/amazon-s3-and-cloudfront.php:3769
187
  #, php-format
188
  msgctxt "Trying to change public access setting for given provider's bucket."
189
  msgid "Can't change Block All Public Access setting for %s buckets."
190
  msgstr ""
191
 
192
+ #: classes/amazon-s3-and-cloudfront.php:3778
193
  msgid "No block public access setting provided."
194
  msgstr ""
195
 
196
+ #: classes/amazon-s3-and-cloudfront.php:3791
197
  msgid "Storage Provider not configured with access credentials."
198
  msgstr ""
199
 
200
+ #: classes/amazon-s3-and-cloudfront.php:3818
201
  msgid "Could not change Block All Public Access status for bucket."
202
  msgstr ""
203
 
204
+ #: classes/amazon-s3-and-cloudfront.php:3835
205
  msgid ""
206
  "<strong>Failed to Enable Block All Public Access</strong> &mdash; We could "
207
  "not enable Block All Public Access. You will need to log in to the AWS "
208
  "Console and do it manually."
209
  msgstr ""
210
 
211
+ #: classes/amazon-s3-and-cloudfront.php:3837
212
  msgid ""
213
  "<strong>Failed to Disable Block All Public Access</strong> &mdash; We could "
214
  "not disable Block All Public Access. You will need to log in to the AWS "
215
  "Console and do it manually."
216
  msgstr ""
217
 
218
+ #: classes/amazon-s3-and-cloudfront.php:3872
219
  #: view/provider-select.php:329
220
  msgctxt "placeholder for hidden secret access key, 39 char max"
221
  msgid "-- not shown --"
222
  msgstr ""
223
 
224
+ #: classes/amazon-s3-and-cloudfront.php:3895
225
  msgid "Key File not valid JSON."
226
  msgstr ""
227
 
228
+ #: classes/amazon-s3-and-cloudfront.php:3907
229
+ #: classes/amazon-s3-and-cloudfront.php:3921
230
+ #: classes/amazon-s3-and-cloudfront.php:3930
231
  msgctxt "missing form field"
232
  msgid " not provided."
233
  msgstr ""
234
 
235
+ #: classes/amazon-s3-and-cloudfront.php:3973
236
  msgctxt "Show the media library tab"
237
  msgid "Media Library"
238
  msgstr ""
239
 
240
+ #: classes/amazon-s3-and-cloudfront.php:3974
241
  msgctxt "Show the addons tab"
242
  msgid "Addons"
243
  msgstr ""
244
 
245
+ #: classes/amazon-s3-and-cloudfront.php:3975
246
  msgctxt "Show the support tab"
247
  msgid "Support"
248
  msgstr ""
249
 
250
+ #: classes/amazon-s3-and-cloudfront.php:4151
251
  #, php-format
252
  msgid ""
253
  "<strong>WP Offload Media</strong> &mdash; The file %s has been given %s "
254
  "permissions in the bucket."
255
  msgstr ""
256
 
257
+ #: classes/amazon-s3-and-cloudfront.php:4170
258
  msgid ""
259
  "<strong>WP Offload Media Requirement Missing</strong> &mdash; Looks like you "
260
  "don't have an image manipulation library installed on this server and "
262
  "Please setup GD or ImageMagick."
263
  msgstr ""
264
 
265
+ #: classes/amazon-s3-and-cloudfront.php:4194
266
+ #, php-format
267
+ msgid ""
268
+ "<strong>Missing Table</strong> &mdash; One or more required database tables "
269
+ "are missing, please check the Diagnostic Info in the Support tab for "
270
+ "details. %s"
271
+ msgstr ""
272
+
273
+ #: classes/amazon-s3-and-cloudfront.php:5016
274
  #, php-format
275
  msgid ""
276
  "<a href=\"%s\">Define your access keys</a> to enable write access to the "
277
  "bucket"
278
  msgstr ""
279
 
280
+ #: classes/amazon-s3-and-cloudfront.php:5023
281
  msgid "Quick Start Guide"
282
  msgstr ""
283
 
284
+ #: classes/amazon-s3-and-cloudfront.php:5025
285
  #, php-format
286
  msgid ""
287
  "Looks like we don't have write access to this bucket. It's likely that the "
290
  "correctly."
291
  msgstr ""
292
 
293
+ #: classes/amazon-s3-and-cloudfront.php:5027
294
  #, php-format
295
  msgid ""
296
  "Looks like we don't have access to the buckets. It's likely that the user "
298
  "Please see our %s for instructions on setting up permissions correctly."
299
  msgstr ""
300
 
301
+ #: classes/amazon-s3-and-cloudfront.php:5195
302
  msgid "WP Offload Media Activation"
303
  msgstr ""
304
 
305
+ #: classes/amazon-s3-and-cloudfront.php:5196
306
  msgid ""
307
  "WP Offload Media Lite and WP Offload Media cannot both be active. We've "
308
  "automatically deactivated WP Offload Media Lite."
309
  msgstr ""
310
 
311
+ #: classes/amazon-s3-and-cloudfront.php:5198
312
  msgid "WP Offload Media Lite Activation"
313
  msgstr ""
314
 
315
+ #: classes/amazon-s3-and-cloudfront.php:5199
316
  msgid ""
317
  "WP Offload Media Lite and WP Offload Media cannot both be active. We've "
318
  "automatically deactivated WP Offload Media."
319
  msgstr ""
320
 
321
+ #: classes/amazon-s3-and-cloudfront.php:5253
322
  msgid "More&nbsp;info&nbsp;&raquo;"
323
  msgstr ""
324
 
325
+ #: classes/amazon-s3-and-cloudfront.php:5333
326
  msgid "this doc"
327
  msgstr ""
328
 
329
+ #: classes/amazon-s3-and-cloudfront.php:5335
330
  msgid "WP Offload Media Feature Removed"
331
  msgstr ""
332
 
333
+ #: classes/amazon-s3-and-cloudfront.php:5336
334
  #, php-format
335
  msgid ""
336
  "You had the \"Always non-SSL\" option selected in your settings, but we've "
341
  "to the old behavior."
342
  msgstr ""
343
 
344
+ #: classes/amazon-s3-and-cloudfront.php:5371
345
  msgid "Offload"
346
  msgstr ""
347
 
348
+ #: classes/amazon-s3-and-cloudfront.php:5475
349
+ msgid "No"
350
+ msgstr ""
351
+
352
+ #: classes/amazon-s3-and-cloudfront.php:5480
353
  msgctxt "Storage provider key name"
354
  msgid "Storage Provider"
355
  msgstr ""
356
 
357
+ #: classes/amazon-s3-and-cloudfront.php:5481
358
  msgctxt "Storage provider name"
359
  msgid "Storage Provider"
360
  msgstr ""
361
 
362
+ #: classes/amazon-s3-and-cloudfront.php:5482
363
  msgctxt "Bucket name"
364
  msgid "Bucket"
365
  msgstr ""
366
 
367
+ #: classes/amazon-s3-and-cloudfront.php:5483
368
  msgctxt "Path to file in bucket"
369
  msgid "Path"
370
  msgstr ""
371
 
372
+ #: classes/amazon-s3-and-cloudfront.php:5484
373
  msgctxt "Location of bucket"
374
  msgid "Region"
375
  msgstr ""
376
 
377
+ #: classes/amazon-s3-and-cloudfront.php:5485
378
  msgctxt "Access control list of the file in bucket"
379
  msgid "Access"
380
  msgstr ""
381
 
382
+ #: classes/amazon-s3-and-cloudfront.php:5486
383
  msgid "URL"
384
  msgstr ""
385
 
386
+ #: classes/amazon-s3-and-cloudfront.php:5487
387
+ msgctxt "Whether or not metadata has been verified"
388
+ msgid "Verified"
389
+ msgstr ""
390
+
391
+ #: classes/amazon-s3-and-cloudfront.php:5740
392
  msgid "Assets Pull"
393
  msgstr ""
394
 
395
+ #: classes/amazon-s3-and-cloudfront.php:5741
396
  msgid ""
397
  "An addon for WP Offload Media to serve your site's JS, CSS, and other "
398
  "enqueued assets from Amazon CloudFront or another CDN."
399
  msgstr ""
400
 
401
+ #: classes/amazon-s3-and-cloudfront.php:5745
402
  msgid "Feature"
403
  msgstr ""
404
 
405
+ #: classes/amazon-s3-and-cloudfront.php:5791
406
  #, php-format
407
  msgid ""
408
  "<strong>Amazon Web Services Plugin No Longer Required</strong> &mdash; As of "
413
  "plugin, it should be safe to deactivate and delete it. %2$s"
414
  msgstr ""
415
 
416
+ #: classes/amazon-s3-and-cloudfront.php:5823
417
  #, php-format
418
  msgid ""
419
  "<strong>WP Offload Media Settings Moved</strong> &mdash; You now define your "
546
  msgid "Settings"
547
  msgstr ""
548
 
549
+ #: classes/as3cf-plugin-compatibility.php:639
550
  #, php-format
551
  msgid "The local directory %s does not exist and could not be created."
552
  msgstr ""
553
 
554
+ #: classes/as3cf-plugin-compatibility.php:640
555
+ #: classes/as3cf-plugin-compatibility.php:652
556
  #: classes/upgrades/upgrade-meta-wp-error.php:81
557
  #, php-format
558
  msgid ""
559
  "There was an error attempting to download the file %s from the bucket: %s"
560
  msgstr ""
561
 
562
+ #: classes/as3cf-plugin-compatibility.php:977
563
  #, php-format
564
  msgid ""
565
  "<strong>Warning:</strong> This site is using PHP %1$s, in a future update WP "
566
  "Offload Media will require PHP %2$s or later. %3$s"
567
  msgstr ""
568
 
569
+ #: classes/items/media-library-item.php:97
570
+ msgid "Empty Attachment ID passed to "
571
+ msgstr ""
572
+
573
+ #: classes/items/media-library-item.php:106
574
+ msgid "Invalid Originator passed to "
575
+ msgstr ""
576
+
577
  #: classes/providers/delivery/another-cdn.php:47
578
  #: classes/providers/delivery/digitalocean-spaces-cdn.php:83
579
  msgid "Fast, No Private Media"
791
  msgid "This item has not been offloaded yet."
792
  msgstr ""
793
 
794
+ #: view/attachment-metabox.php:56
795
  msgid "File does not exist on server"
796
  msgstr ""
797
 
798
+ #: view/attachment-metabox.php:64
799
  msgid "File exists on server"
800
  msgstr ""
801
 
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: uploads, amazon, s3, amazon s3, digitalocean, digitalocean spaces, google
4
  Requires at least: 4.9
5
  Tested up to: 5.5
6
  Requires PHP: 5.5
7
- Stable tag: 2.4.4
8
  License: GPLv3
9
 
10
  Copies files to Amazon S3, DigitalOcean Spaces or Google Cloud Storage as they are uploaded to the Media Library. Optionally configure Amazon CloudFront or another CDN for faster delivery.
@@ -81,6 +81,13 @@ This version requires PHP 5.3.3+ and the Amazon Web Services plugin
81
 
82
  == Changelog ==
83
 
 
 
 
 
 
 
 
84
  = WP Offload Media Lite 2.4.4 - 2020-09-08 =
85
  * Improvement: Updated AWS PHP SDK to v3.151.6
86
  * Bug fix: Files for duplicate thumbnail sizes not removed from server after initial offload
4
  Requires at least: 4.9
5
  Tested up to: 5.5
6
  Requires PHP: 5.5
7
+ Stable tag: 2.5
8
  License: GPLv3
9
 
10
  Copies files to Amazon S3, DigitalOcean Spaces or Google Cloud Storage as they are uploaded to the Media Library. Optionally configure Amazon CloudFront or another CDN for faster delivery.
81
 
82
  == Changelog ==
83
 
84
+ = WP Offload Media Lite 2.5 - 2020-11-11 =
85
+ * [Release Summary Blog Post](https://deliciousbrains.com/wp-offload-media-2-5-released/?utm_campaign=changelogs&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting)
86
+ * Improvement: [Error notice shown](https://deliciousbrains.com/wp-offload-media/doc/missing-table-error-notice/?utm_campaign=changelogs&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting) when plugin's required custom table(s) missing
87
+ * Improvement: [Diagnostic Info](https://deliciousbrains.com/wp-offload-media/doc/missing-table-error-notice/?utm_campaign=changelogs&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting#diagnostic-info) shows status of plugin's required custom tables
88
+ * Bug fix: wp_get_original_image_path function does not return provider URL when local files removed
89
+ * Bug fix: File missing notices recorded in debug.log when regenerating thumbnails and Remove Files From Server turned on
90
+
91
  = WP Offload Media Lite 2.4.4 - 2020-09-08 =
92
  * Improvement: Updated AWS PHP SDK to v3.151.6
93
  * Bug fix: Files for duplicate thumbnail sizes not removed from server after initial offload
view/attachment-metabox.php CHANGED
@@ -44,6 +44,13 @@ $is_local_removable = $is_current_provider && $local_file_exists && in_array( 'r
44
  <?php echo $this->get_acl_value_string( $provider_object['acl'], $post->ID ); ?>
45
  </div>
46
  </div>
 
 
 
 
 
 
 
47
  <?php if ( $is_downloadable ) : ?>
48
  <div class="misc-pub-section">
49
  <div class="not-copied"><?php _e( 'File does not exist on server', 'amazon-s3-and-cloudfront' ); ?></div>
44
  <?php echo $this->get_acl_value_string( $provider_object['acl'], $post->ID ); ?>
45
  </div>
46
  </div>
47
+ <?php
48
+ if ( isset( $provider_object['is_verified'] ) && empty( $provider_object['is_verified'] ) ) : ?>
49
+ <div class="misc-pub-section">
50
+ <div class="s3-key"><?php echo $this->get_media_action_strings( 'is_verified' ); ?>:</div>
51
+ <div id="as3cf-is-verified" class="s3-value"><?php echo $this->get_media_action_strings( 'not_verified' ); ?></div>
52
+ </div>
53
+ <?php endif; ?>
54
  <?php if ( $is_downloadable ) : ?>
55
  <div class="misc-pub-section">
56
  <div class="not-copied"><?php _e( 'File does not exist on server', 'amazon-s3-and-cloudfront' ); ?></div>
wordpress-s3.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: WP Offload Media Lite
4
  Plugin URI: http://wordpress.org/extend/plugins/amazon-s3-and-cloudfront/
5
  Description: Automatically copies media uploads to Amazon S3, DigitalOcean Spaces or Google Cloud Storage for storage and delivery. Optionally configure Amazon CloudFront or another CDN for even faster delivery.
6
  Author: Delicious Brains
7
- Version: 2.4.4
8
  Author URI: https://deliciousbrains.com/
9
  Network: True
10
  Text Domain: amazon-s3-and-cloudfront
@@ -26,7 +26,7 @@ Domain Path: /languages/
26
  // Then completely rewritten.
27
  */
28
 
29
- $GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['version'] = '2.4.4';
30
 
31
  require_once dirname( __FILE__ ) . '/classes/as3cf-compatibility-check.php';
32
 
4
  Plugin URI: http://wordpress.org/extend/plugins/amazon-s3-and-cloudfront/
5
  Description: Automatically copies media uploads to Amazon S3, DigitalOcean Spaces or Google Cloud Storage for storage and delivery. Optionally configure Amazon CloudFront or another CDN for even faster delivery.
6
  Author: Delicious Brains
7
+ Version: 2.5
8
  Author URI: https://deliciousbrains.com/
9
  Network: True
10
  Text Domain: amazon-s3-and-cloudfront
26
  // Then completely rewritten.
27
  */
28
 
29
+ $GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['version'] = '2.5';
30
 
31
  require_once dirname( __FILE__ ) . '/classes/as3cf-compatibility-check.php';
32