WP Offload S3 Lite - Version 1.4

Version Description

= 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 1.4
Comparing to
See all releases

Code changes from version 1.3.2 to 1.4

Files changed (266) hide show
  1. README.md +21 -7
  2. assets/js/script.js +1 -1
  3. assets/js/script.min.js +1 -1
  4. classes/amazon-s3-and-cloudfront.php +273 -227
  5. classes/amazon-web-services.php +0 -167
  6. classes/as3cf-compatibility-check.php +3 -3
  7. classes/as3cf-filter.php +12 -0
  8. classes/as3cf-plugin-base.php +11 -27
  9. classes/as3cf-plugin-compatibility.php +35 -48
  10. classes/as3cf-stream-wrapper.php +0 -103
  11. classes/as3cf-utils.php +26 -0
  12. classes/null-s3-client.php +0 -34
  13. classes/providers/aws-provider.php +476 -0
  14. classes/providers/null-provider.php +34 -0
  15. classes/providers/provider.php +491 -0
  16. classes/providers/streams/aws-s3-stream-wrapper.php +78 -0
  17. classes/upgrades/upgrade-file-sizes.php +13 -11
  18. classes/upgrades/upgrade-meta-wp-error.php +1 -1
  19. languages/amazon-s3-and-cloudfront-en.pot +85 -82
  20. readme.txt +21 -7
  21. vendor/Aws2/aws/aws-sdk-php/NOTICE.md +0 -112
  22. vendor/Aws2/aws/aws-sdk-php/composer.json +0 -51
  23. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Aws.php +0 -97
  24. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Client/AbstractClient.php +0 -215
  25. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Client/AwsClientInterface.php +0 -107
  26. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Client/ClientBuilder.php +0 -429
  27. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Client/DefaultClient.php +0 -63
  28. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Client/ExpiredCredentialsChecker.php +0 -68
  29. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Client/ThrottlingErrorChecker.php +0 -60
  30. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Client/UploadBodyListener.php +0 -87
  31. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Client/UserAgentListener.php +0 -58
  32. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Command/AwsQueryVisitor.php +0 -108
  33. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Command/JsonCommand.php +0 -43
  34. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Command/QueryCommand.php +0 -49
  35. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Command/XmlResponseLocationVisitor.php +0 -63
  36. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Credentials/AbstractCredentialsDecorator.php +0 -120
  37. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Credentials/AbstractRefreshableCredentials.php +0 -80
  38. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Credentials/CacheableCredentials.php +0 -69
  39. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Credentials/Credentials.php +0 -270
  40. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Credentials/CredentialsInterface.php +0 -88
  41. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Credentials/NullCredentials.php +0 -59
  42. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Credentials/RefreshableInstanceProfileCredentials.php +0 -75
  43. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Enum.php +0 -51
  44. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Enum/ClientOptions.php +0 -142
  45. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Enum/DateFormat.php +0 -30
  46. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Enum/Region.php +0 -52
  47. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Enum/Size.php +0 -46
  48. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Enum/Time.php +0 -39
  49. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Enum/UaString.php +0 -49
  50. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/AwsExceptionInterface.php +0 -30
  51. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/BadMethodCallException.php +0 -24
  52. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/DomainException.php +0 -24
  53. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/ExceptionFactoryInterface.php +0 -35
  54. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/ExceptionListener.php +0 -55
  55. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/InstanceProfileCredentialsException.php +0 -47
  56. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/InvalidArgumentException.php +0 -24
  57. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/LogicException.php +0 -24
  58. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/MultipartUploadException.php +0 -47
  59. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/NamespaceExceptionFactory.php +0 -89
  60. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/OutOfBoundsException.php +0 -24
  61. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/OverflowException.php +0 -24
  62. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/Parser/AbstractJsonExceptionParser.php +0 -54
  63. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/Parser/DefaultXmlExceptionParser.php +0 -93
  64. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/Parser/ExceptionParserInterface.php +0 -41
  65. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/Parser/JsonQueryExceptionParser.php +0 -39
  66. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/Parser/JsonRestExceptionParser.php +0 -44
  67. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/RequiredExtensionNotLoadedException.php +0 -24
  68. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/RuntimeException.php +0 -24
  69. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/ServiceResponseException.php +0 -194
  70. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/TransferException.php +0 -25
  71. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Exception/UnexpectedValueException.php +0 -24
  72. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Facade/Facade.php +0 -65
  73. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Facade/FacadeInterface.php +0 -34
  74. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Facade/facade-classes.php +0 -249
  75. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Hash/ChunkHash.php +0 -77
  76. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Hash/ChunkHashInterface.php +0 -49
  77. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Hash/HashUtils.php +0 -70
  78. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Hash/TreeHash.php +0 -169
  79. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/HostNameUtils.php +0 -75
  80. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/InstanceMetadata/InstanceMetadataClient.php +0 -81
  81. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/InstanceMetadata/Waiter/ServiceAvailable.php +0 -46
  82. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Iterator/AwsResourceIterator.php +0 -152
  83. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Iterator/AwsResourceIteratorFactory.php +0 -84
  84. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractTransfer.php +0 -219
  85. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractTransferState.php +0 -145
  86. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractUploadBuilder.php +0 -131
  87. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractUploadId.php +0 -81
  88. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractUploadPart.php +0 -91
  89. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/TransferInterface.php +0 -61
  90. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/TransferStateInterface.php +0 -84
  91. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/UploadIdInterface.php +0 -38
  92. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/UploadPartInterface.php +0 -44
  93. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Resources/aws-config.php +0 -17
  94. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Resources/public-endpoints.php +0 -3
  95. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Resources/sdk1-config.php +0 -17
  96. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/RulesEndpointProvider.php +0 -55
  97. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Signature/AbstractSignature.php +0 -39
  98. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Signature/EndpointSignatureInterface.php +0 -41
  99. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureInterface.php +0 -46
  100. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureListener.php +0 -76
  101. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureV2.php +0 -86
  102. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureV3Https.php +0 -47
  103. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureV4.php +0 -360
  104. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Waiter/AbstractResourceWaiter.php +0 -48
  105. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Waiter/AbstractWaiter.php +0 -120
  106. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Waiter/CallableWaiter.php +0 -73
  107. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Waiter/CompositeWaiterFactory.php +0 -81
  108. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Waiter/ConfigResourceWaiter.php +0 -185
  109. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Waiter/ResourceWaiterInterface.php +0 -33
  110. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Waiter/WaiterClassFactory.php +0 -95
  111. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Waiter/WaiterConfig.php +0 -64
  112. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Waiter/WaiterConfigFactory.php +0 -86
  113. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Waiter/WaiterFactoryInterface.php +0 -40
  114. vendor/Aws2/aws/aws-sdk-php/src/Aws/Common/Waiter/WaiterInterface.php +0 -56
  115. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/AcpListener.php +0 -68
  116. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/BucketStyleListener.php +0 -73
  117. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Command/S3Command.php +0 -57
  118. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Enum/CannedAcl.php +0 -31
  119. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Enum/EncodingType.php +0 -26
  120. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Enum/Event.php +0 -26
  121. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Enum/GranteeType.php +0 -28
  122. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Enum/Group.php +0 -28
  123. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Enum/MFADelete.php +0 -27
  124. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Enum/MetadataDirective.php +0 -27
  125. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Enum/Payer.php +0 -27
  126. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Enum/Permission.php +0 -30
  127. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Enum/Protocol.php +0 -27
  128. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Enum/ServerSideEncryption.php +0 -26
  129. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Enum/Status.php +0 -27
  130. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Enum/Storage.php +0 -28
  131. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Enum/StorageClass.php +0 -27
  132. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/AccessDeniedException.php +0 -24
  133. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/AccountProblemException.php +0 -24
  134. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/AmbiguousGrantByEmailAddressException.php +0 -24
  135. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/BadDigestException.php +0 -24
  136. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/BucketAlreadyExistsException.php +0 -24
  137. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/BucketAlreadyOwnedByYouException.php +0 -24
  138. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/BucketNotEmptyException.php +0 -24
  139. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/CredentialsNotSupportedException.php +0 -24
  140. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/CrossLocationLoggingProhibitedException.php +0 -24
  141. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/DeleteMultipleObjectsException.php +0 -46
  142. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/EntityTooLargeException.php +0 -24
  143. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/EntityTooSmallException.php +0 -24
  144. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/ExpiredTokenException.php +0 -24
  145. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/IllegalVersioningConfigurationException.php +0 -24
  146. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/IncompleteBodyException.php +0 -24
  147. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/IncorrectNumberOfFilesInPostRequestException.php +0 -24
  148. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InlineDataTooLargeException.php +0 -24
  149. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InternalErrorException.php +0 -24
  150. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidAccessKeyIdException.php +0 -24
  151. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidAddressingHeaderException.php +0 -24
  152. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidArgumentException.php +0 -24
  153. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidBucketNameException.php +0 -24
  154. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidBucketStateException.php +0 -24
  155. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidDigestException.php +0 -24
  156. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidLocationConstraintException.php +0 -24
  157. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidPartException.php +0 -24
  158. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidPartOrderException.php +0 -24
  159. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidPayerException.php +0 -24
  160. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidPolicyDocumentException.php +0 -24
  161. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidRangeException.php +0 -24
  162. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidRequestException.php +0 -24
  163. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidSOAPRequestException.php +0 -24
  164. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidSecurityException.php +0 -24
  165. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidStorageClassException.php +0 -24
  166. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidTagErrorException.php +0 -25
  167. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidTargetBucketForLoggingException.php +0 -24
  168. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidTokenException.php +0 -24
  169. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/InvalidURIException.php +0 -24
  170. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/KeyTooLongException.php +0 -24
  171. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/MalformedACLErrorException.php +0 -24
  172. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/MalformedPOSTRequestException.php +0 -24
  173. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/MalformedXMLException.php +0 -24
  174. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/MaxMessageLengthExceededException.php +0 -24
  175. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/MaxPostPreDataLengthExceededErrorException.php +0 -24
  176. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/MetadataTooLargeException.php +0 -24
  177. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/MethodNotAllowedException.php +0 -24
  178. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/MissingAttachmentException.php +0 -24
  179. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/MissingContentLengthException.php +0 -24
  180. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/MissingRequestBodyErrorException.php +0 -24
  181. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/MissingSecurityElementException.php +0 -24
  182. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/MissingSecurityHeaderException.php +0 -24
  183. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/NoLoggingStatusForKeyException.php +0 -24
  184. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/NoSuchBucketException.php +0 -24
  185. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/NoSuchBucketPolicyException.php +0 -24
  186. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/NoSuchCORSConfigurationException.php +0 -24
  187. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/NoSuchKeyException.php +0 -24
  188. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/NoSuchLifecycleConfigurationException.php +0 -24
  189. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/NoSuchTagSetException.php +0 -24
  190. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/NoSuchUploadException.php +0 -24
  191. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/NoSuchVersionException.php +0 -24
  192. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/NoSuchWebsiteConfigurationException.php +0 -24
  193. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/NotImplementedException.php +0 -24
  194. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/NotSignedUpException.php +0 -24
  195. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/NotSuchBucketPolicyException.php +0 -24
  196. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/ObjectAlreadyInActiveTierErrorException.php +0 -24
  197. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/ObjectNotInActiveTierErrorException.php +0 -24
  198. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/OperationAbortedException.php +0 -24
  199. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/Parser/S3ExceptionParser.php +0 -65
  200. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/PermanentRedirectException.php +0 -24
  201. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/PreconditionFailedException.php +0 -24
  202. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/RedirectException.php +0 -24
  203. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/RequestIsNotMultiPartContentException.php +0 -24
  204. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/RequestTimeTooSkewedException.php +0 -24
  205. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/RequestTimeoutException.php +0 -24
  206. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/RequestTorrentOfBucketErrorException.php +0 -24
  207. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/S3Exception.php +0 -25
  208. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/ServiceUnavailableException.php +0 -24
  209. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/SignatureDoesNotMatchException.php +0 -24
  210. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/SlowDownException.php +0 -24
  211. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/TemporaryRedirectException.php +0 -24
  212. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/TokenRefreshRequiredException.php +0 -24
  213. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/TooManyBucketsException.php +0 -24
  214. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/UnexpectedContentException.php +0 -24
  215. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/UnresolvableGrantByEmailAddressException.php +0 -24
  216. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Exception/UserKeyMustBeSpecifiedException.php +0 -24
  217. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/IncompleteMultipartUploadChecker.php +0 -44
  218. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Iterator/ListBucketsIterator.php +0 -45
  219. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Iterator/ListMultipartUploadsIterator.php +0 -43
  220. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Iterator/ListObjectVersionsIterator.php +0 -45
  221. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Iterator/ListObjectsIterator.php +0 -62
  222. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Iterator/OpendirIterator.php +0 -75
  223. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/Acp.php +0 -208
  224. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/AcpBuilder.php +0 -120
  225. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/ClearBucket.php +0 -161
  226. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/DeleteObjectsBatch.php +0 -72
  227. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/DeleteObjectsTransfer.php +0 -112
  228. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/Grant.php +0 -114
  229. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/Grantee.php +0 -211
  230. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/AbstractTransfer.php +0 -83
  231. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/ParallelTransfer.php +0 -100
  232. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/SerialTransfer.php +0 -65
  233. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/TransferState.php +0 -38
  234. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/UploadBuilder.php +0 -243
  235. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/UploadId.php +0 -30
  236. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/UploadPart.php +0 -62
  237. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Model/PostObject.php +0 -229
  238. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Resources/s3-2006-03-01.php +0 -17
  239. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/ResumableDownload.php +0 -150
  240. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/S3Client.php +0 -524
  241. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/S3Md5Listener.php +0 -65
  242. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/S3Signature.php +0 -191
  243. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/S3SignatureInterface.php +0 -25
  244. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/S3SignatureV4.php +0 -53
  245. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/SocketTimeoutChecker.php +0 -60
  246. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/SseCpkListener.php +0 -54
  247. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/StreamWrapper.php +0 -757
  248. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Sync/AbstractSync.php +0 -114
  249. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Sync/AbstractSyncBuilder.php +0 -359
  250. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Sync/ChangedFilesIterator.php +0 -105
  251. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Sync/DownloadSync.php +0 -83
  252. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Sync/DownloadSyncBuilder.php +0 -97
  253. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Sync/FilenameConverterInterface.php +0 -32
  254. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Sync/KeyConverter.php +0 -55
  255. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Sync/UploadSync.php +0 -61
  256. vendor/Aws2/aws/aws-sdk-php/src/Aws/S3/Sync/UploadSyncBuilder.php +0 -147
  257. vendor/Aws2/guzzle/guzzle/CHANGELOG.md +0 -751
  258. vendor/Aws2/guzzle/guzzle/LICENSE +0 -19
  259. vendor/Aws2/guzzle/guzzle/README.md +0 -57
  260. vendor/Aws2/guzzle/guzzle/UPGRADING.md +0 -537
  261. vendor/Aws2/guzzle/guzzle/build.xml +0 -45
  262. vendor/Aws2/guzzle/guzzle/composer.json +0 -82
  263. vendor/Aws2/guzzle/guzzle/phar-stub.php +0 -9
  264. vendor/Aws2/guzzle/guzzle/phing/build.properties.dist +0 -16
  265. vendor/Aws2/guzzle/guzzle/phing/imports/dependencies.xml +0 -33
  266. vendor/Aws2/guzzle/guzzle/phing/imports/deploy.xml +0 -103
README.md CHANGED
@@ -3,7 +3,8 @@
3
  **Tags:** uploads, amazon, s3, amazon s3, mirror, admin, media, cdn, cloudfront
4
  **Requires at least:** 4.6
5
  **Tested up to:** 4.9
6
- **Stable tag:** 1.3.2
 
7
  **License:** GPLv3
8
 
9
  Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery.
@@ -23,8 +24,8 @@ If you're adding this plugin to a site that's been around for a while, your exis
23
  * Upload existing Media Library to Amazon S3
24
  * Control Amazon S3 files from the Media Library
25
  * [Assets addon](https://deliciousbrains.com/wp-offload-s3/?utm_campaign=WP%2BOffload%2BS3&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting&utm_content=assets%2Baddon#addons) - Serve your CSS & JS from Amazon S3/CloudFront
26
- * [WooCommerce addon](https://deliciousbrains.com/wp-offload-s3/?utm_campaign=WP%2BOffload%2BS3&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting&utm_content=woocommerce%2Baddon#addons)
27
- * [Easy Digital Downloads addon](https://deliciousbrains.com/wp-offload-s3/?utm_campaign=WP%2BOffload%2BS3&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting&utm_content=edd%2Baddon#addons)
28
  * PriorityExpert™ email support
29
 
30
  [Compare pro vs free →](https://deliciousbrains.com/wp-offload-s3/upgrade/?utm_campaign=WP%2BOffload%2BS3&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting)
@@ -39,10 +40,11 @@ which is a fork of [Amazon S3 for WordPress](http://wordpress.org/extend/plugins
39
 
40
  ## Installation ##
41
 
42
- 1. Install the required [Amazon Web Services plugin](http://wordpress.org/extend/plugins/amazon-web-services/) using WordPress' built-in installer
43
- 2. Follow the instructions to setup your AWS access keys
44
- 3. Install this plugin using WordPress' built-in installer
45
- 4. Access the *S3 and CloudFront* option under *AWS* and configure
 
46
 
47
  ## Frequently Asked Questions ##
48
 
@@ -69,6 +71,18 @@ This version requires PHP 5.3.3+ and the Amazon Web Services plugin
69
 
70
  ## Changelog ##
71
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  ### WP Offload S3 Lite 1.3.2 - 2018-02-22 ###
73
  * Bug fix: Fatal error: Uncaught Error: Call to undefined method Composer\Autoload\ClassLoader::setClassMapAuthoritative()
74
  * Bug fix: AWS keys stored in database by Amazon Web Services plugin are not being migrated to new settings record
3
  **Tags:** uploads, amazon, s3, amazon s3, mirror, admin, media, cdn, cloudfront
4
  **Requires at least:** 4.6
5
  **Tested up to:** 4.9
6
+ **Requires PHP:** 5.5
7
+ **Stable tag:** 1.4
8
  **License:** GPLv3
9
 
10
  Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery.
24
  * Upload existing Media Library to Amazon S3
25
  * Control Amazon S3 files from the Media Library
26
  * [Assets addon](https://deliciousbrains.com/wp-offload-s3/?utm_campaign=WP%2BOffload%2BS3&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting&utm_content=assets%2Baddon#addons) - Serve your CSS & JS from Amazon S3/CloudFront
27
+ * [WooCommerce integration](https://deliciousbrains.com/wp-offload-s3/?utm_campaign=WP%2BOffload%2BS3&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting&utm_content=woocommerce%2Baddon#integrations)
28
+ * [Easy Digital Downloads integration](https://deliciousbrains.com/wp-offload-s3/?utm_campaign=WP%2BOffload%2BS3&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting&utm_content=edd%2Baddon#integrations)
29
  * PriorityExpert™ email support
30
 
31
  [Compare pro vs free →](https://deliciousbrains.com/wp-offload-s3/upgrade/?utm_campaign=WP%2BOffload%2BS3&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting)
40
 
41
  ## Installation ##
42
 
43
+ 1. Install this plugin using WordPress' built-in installer
44
+ 2. Access the *Offload S3* option under *Settings*
45
+ 3. Follow the instructions to setup your AWS access keys and configure
46
+
47
+ Check out the [Quick Start Guide](https://deliciousbrains.com/wp-offload-s3/doc/quick-start-guide/?utm_campaign=WP%2BOffload%2BS3&utm_source=wordpress.org&utm_medium=free%2Bplugin%2Blisting) for more information on configuring WP Offload S3.
48
 
49
  ## Frequently Asked Questions ##
50
 
71
 
72
  ## Changelog ##
73
 
74
+ ### WP Offload S3 Lite 1.4 - 2018-06-12 ###
75
+ * New: Using AWS PHP SDK v3
76
+ * New: Requires PHP 5.5+
77
+ * Improvement: Supported AWS S3 regions updated and names changed to match current AWS nomenclature
78
+ * Bug fix: PHP Warning: Declaration of AS3CF_Stream_Wrapper::register should be compatible with Aws\S3\StreamWrapper::register
79
+ * Bug fix: File size not stored in _wp_attachment_metadata for audio/video files
80
+ * Bug fix: Image srcset uses full size image if metadata size is stored as string
81
+ * Bug fix: PHP Warning: preg_match() expects parameter 2 to be string, array given
82
+ * Bug fix: SQL syntax error when using `attachment_url_to_postid()` with non-ascii file name
83
+ * Tested: WordPress 4.9.6
84
+ * Tested: Gutenberg 3.0
85
+
86
  ### WP Offload S3 Lite 1.3.2 - 2018-02-22 ###
87
  * Bug fix: Fatal error: Uncaught Error: Call to undefined method Composer\Autoload\ClassLoader::setClassMapAuthoritative()
88
  * Bug fix: AWS keys stored in database by Amazon Web Services plugin are not being migrated to new settings record
assets/js/script.js CHANGED
@@ -619,7 +619,7 @@
619
  var prefix = $objectPrefix.val();
620
 
621
  if ( '' !== prefix ) {
622
- prefix = '&prefix=' + encodeURIComponent( prefix );
623
  }
624
 
625
  var url = as3cf.aws_bucket_link + bucket + prefix;
619
  var prefix = $objectPrefix.val();
620
 
621
  if ( '' !== prefix ) {
622
+ prefix = as3cf.aws_bucket_link_param + encodeURIComponent( prefix );
623
  }
624
 
625
  var url = as3cf.aws_bucket_link + bucket + prefix;
assets/js/script.min.js CHANGED
@@ -1 +1 @@
1
- !function(a,b){function c(b){return a("#"+b+" .as3cf-main-settings form").find("input:not(.no-compare)").serialize()}function d(a){var b=k.find("#"+a),c=b.find("input[type=checkbox]");b.toggleClass("on").find("span").toggleClass("checked");var d=b.find("span.on").hasClass("checked");c.prop("checked",d).trigger("change")}function e(b){var c=b.next(".as3cf-validation-error"),d=a("#"+k.attr("id")+' form button[type="submit"]'),e=/[^a-zA-Z0-9\.\-]/;e.test(b.val())?(c.show(),d.prop("disabled",!0)):(c.hide(),d.prop("disabled",!1))}function f(){var c=a("#"+b.prefix+"-bucket").val(),d=k.find('input[name="object-prefix"]'),e=d.val();""!==e&&(e="&prefix="+encodeURIComponent(e));var f=as3cf.aws_bucket_link+c+e;a("#"+b.prefix+"-view-bucket").attr("href",f)}function g(){a(".as3cf-url-preview").html("Generating...");var b={_nonce:as3cf.nonces.get_url_preview};a.each(a("#tab-"+as3cf.tabs.defaultTab+" .as3cf-main-settings form").serializeArray(),function(c,d){var e=d.name,f=d.value;e=e.replace("[]",""),b[e]=void 0===b[e]?f:a.isArray(b[e])?b[e].concat(f):[b[e],f]}),b.action="as3cf-get-url-preview",a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:b,error:function(a,b,c){alert(as3cf.strings.get_url_preview_error+c)},success:function(b,c,d){"undefined"!=typeof b.success?a(".as3cf-url-preview").html(b.url):alert(as3cf.strings.get_url_preview_error+b.error)}})}function h(){a("#as3cf-remove-local-file").is(":checked")&&a("#as3cf-serve-from-s3").is(":not(:checked)")?a("#as3cf-lost-files-notice").show():a("#as3cf-lost-files-notice").hide()}function i(){a("#as3cf-remove-local-file").is(":checked")?a("#as3cf-remove-local-notice").show():a("#as3cf-remove-local-notice").hide()}function j(){return"#"+as3cf.tabs.defaultTab===location.hash?void(location.hash=""):(as3cf.tabs.toggle(location.hash.replace("#",""),!0),void a(document).trigger("as3cf.tabRendered",[location.hash.replace("#","")]))}var k,l={},m=/[^a-z0-9.-]/,n=!1,o=a("body"),p=a(".as3cf-tab"),q=a(".as3cf-settings");as3cf.tabs={defaultTab:"media",toggle:function(c,d){c=as3cf.tabs.sanitizeHash(c),p.hide(),k=a("#tab-"+c),k.show(),a(".nav-tab").removeClass("nav-tab-active"),a('a.nav-tab[data-tab="'+c+'"]').addClass("nav-tab-active"),a(".as3cf-main").data("tab",c),k.data("prefix")&&(b.prefix=k.data("prefix")),d||a(".as3cf-updated").removeClass("show"),"support"===c&&as3cf.tabs.getDiagnosticInfo()},getDiagnosticInfo:function(){var b=a(".debug-log-textarea");b.html(as3cf.strings.get_diagnostic_info);var c={action:"as3cf-get-diagnostic-info",_nonce:as3cf.nonces.get_diagnostic_info};a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:c,error:function(a,c,d){b.html(d)},success:function(a,c,d){"undefined"!=typeof a.success?b.html(a.diagnostic_info):(b.html(as3cf.strings.get_diagnostic_info_error),b.append(a.error))}})},sanitizeHash:function(b){var c=a("#tab-"+b);return 0===c.length&&(b=as3cf.tabs.defaultTab),b}},as3cf.buckets={validLength:3,bucketSelectLock:!1,loadList:function(c){"undefined"==typeof c&&(c=!1);var d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-list"),e=a("#"+b.prefix+"-bucket").val();if(!1===c&&d.find("li").length>1)return a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected"),void this.scrollToSelected();d.html('<li class="loading">'+d.data("working")+"</li>");var f={action:b.prefix+"-get-buckets",_nonce:window[b.prefix.replace(/-/g,"_")].nonces.get_buckets},g=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:f,error:function(a,b,c){d.html(""),g.showError(as3cf.strings.get_buckets_error,c,"as3cf-bucket-select")},success:function(b,c,f){d.html(""),"undefined"!=typeof b.success?(a(".as3cf-bucket-error").hide(),a(b.buckets).each(function(a,b){var c=b.Name===e?"selected":"";d.append('<li><a class="'+c+'" href="#" data-bucket="'+b.Name+'"><span class="bucket"><span class="dashicons dashicons-portfolio"></span> '+b.Name+'</span><span class="spinner"></span></span></a></li>')}),g.scrollToSelected()):g.showError(as3cf.strings.get_buckets_error,b.error,"as3cf-bucket-select")}})},scrollToSelected:function(){if(a(".as3cf-bucket-list a.selected").length){var b=a("ul.as3cf-bucket-list li").first().position().top+150;a(".as3cf-bucket-list").animate({scrollTop:a("ul.as3cf-bucket-list li a.selected").position().top-b})}},resetModal:function(){var c=a(".as3cf-bucket-container."+b.prefix);!1===k.hasClass("as3cf-has-bucket")||"manual"===a("#"+b.prefix+"-bucket-select").val()?(c.find(".as3cf-bucket-manual").show().siblings().hide(),c.find(".bucket-actions.manual").show().siblings(".bucket-actions").hide()):(c.find(".as3cf-bucket-select").show().siblings().hide(),c.find(".bucket-actions.select").show().siblings(".bucket-actions").hide(),this.loadList(n),n=!1),c.find(".as3cf-bucket-error").hide();var d=a("#"+b.prefix+"-bucket").val();c.find(".as3cf-bucket-manual .as3cf-bucket-name").val(d),this.bucketSelectLock=!1},saveManual:function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),d=c.find(".as3cf-bucket-name"),e=c.find("button[type=submit]"),f=d.val(),g=e.first().text();if(f===a("#"+b.prefix+"-active-bucket").text())return a(".as3cf-bucket-error").hide(),k.addClass("as3cf-has-bucket"),void b.close();a(".as3cf-bucket-error").hide(),e.text(e.data("working")),e.prop("disabled",!0);var h={action:b.prefix+"-manual-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.manual_bucket},i=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:h,error:function(a,b,c){e.text(g),i.showError(as3cf.strings.save_bucket_error,c,"as3cf-bucket-manual")},success:function(c,d,h){e.text(g),e.prop("disabled",!1),"undefined"!=typeof c.success?(i.set(f,c.region,c.can_write),a("#"+b.prefix+"-bucket-select").val("manual"),a(".as3cf-bucket-list a").removeClass("selected").filter('[data-bucket="'+f+'"]').addClass("selected"),n=!0,as3cf.showSettingsSavedNotice()):i.showError(as3cf.strings.save_bucket_error,c.error,"as3cf-bucket-manual")}})},saveSelected:function(c){var d=a(".as3cf-bucket-list");if(!this.bucketSelectLock){if(this.bucketSelectLock=!0,c.hasClass("selected"))return k.addClass("as3cf-has-bucket"),void b.close();var e=a(".as3cf-bucket-list a.selected").data("bucket");a(".as3cf-bucket-list a").removeClass("selected"),c.addClass("selected"),d.addClass("saving"),c.find(".spinner").show().css("visibility","visible");var f=c.data("bucket"),g={action:b.prefix+"-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.save_bucket},h=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:g,error:function(b,c,f){d.removeClass("saving"),h.showError(as3cf.strings.save_bucket_error,f,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected")},success:function(g,i,j){c.find(".spinner").hide().css("visibility","hidden"),d.removeClass("saving"),"undefined"!=typeof g.success?(h.set(f,g.region,g.can_write),a("#"+b.prefix+"-bucket-select").val(""),as3cf.showSettingsSavedNotice()):(h.showError(as3cf.strings.save_bucket_error,g.error,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected"))}})}},disabledButtons:function(){if(0!==a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form").length){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form"),d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");c.find(".as3cf-bucket-name").val().length<3?c.find("button[type=submit]").prop("disabled",!0):c.find("button[type=submit]").prop("disabled",!1),d.find(".as3cf-bucket-name").val().length<3?d.find("button[type=submit]").prop("disabled",!0):d.find("button[type=submit]").prop("disabled",!1)}},showError:function(b,c,d){var e=a(".as3cf-bucket-container").children(":visible"),f=e.find(".as3cf-bucket-error");d="undefined"==typeof d?null:d,d&&!e.hasClass(d)||(f.find("span.title").html(b+" &mdash;"),f.find("span.message").html(c),f.show(),this.bucketSelectLock=!1)},set:function(e,h,i){var j=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),m=a("#"+b.prefix+"-active-bucket");if("as3cf"===b.prefix&&0===m.text().trim().length){d("as3cf-copy-to-s3-wrap"),d("as3cf-serve-from-s3-wrap");var n=k.attr("id");l[n]=c(n)}a(".as3cf-error.fatal").hide(),m.text(e),j.find(".as3cf-bucket-name").val(e),a("#"+b.prefix+"-bucket").val(e),a("#"+b.prefix+"-region").val(h),a(".updated").not(".as3cf-notice").show(),k.addClass("as3cf-has-bucket"),k.find(".as3cf-can-write-error").toggle(!i),k.find(".as3cf-bucket-error").hide(),"as3cf"===b.prefix&&g(),f(),b.close(function(){k.trigger("bucket-change",[i]),as3cf.buckets.bucketSelectLock=!1})},create:function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form"),d=c.find(".as3cf-bucket-name"),e=c.find(".bucket-create-region"),f=c.find("button[type=submit]"),g=d.val(),h=f.text();a(".as3cf-bucket-error").hide(),f.text(f.data("working")),f.prop("disabled",!0);var i={action:b.prefix+"-create-bucket",bucket_name:g,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.create_bucket};e.val()&&(i.region=e.val());var j=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:i,error:function(a,b,c){f.text(h),j.showError(as3cf.strings.create_bucket_error,c,"as3cf-bucket-create")},success:function(b,c,e){f.text(h),f.prop("disabled",!1),"undefined"!=typeof b.success?(j.set(g,b.region,b.can_write),a(".as3cf-bucket-select-region").hide(),a(".as3cf-bucket-select-region").prop("selected",!1),d.val(""),f.prop("disabled",!0),n=!0,as3cf.showSettingsSavedNotice()):j.showError(as3cf.strings.create_bucket_error,b.error,"as3cf-bucket-create")}})},isValidName:function(a){return!(a.length<3||a.length>63)&&!0!==m.test(a)},updateNameNotice:function(b){var c=null;!0===m.test(b)?c=as3cf.strings.create_bucket_invalid_chars:b.length<3?c=as3cf.strings.create_bucket_name_short:b.length>63&&(c=as3cf.strings.create_bucket_name_long),c&&b.length>0?a(".as3cf-invalid-bucket-name").html(c):a(".as3cf-invalid-bucket-name").html("")}},as3cf.reloadUpdated=function(){var a=location.pathname+location.search;location.search.match(/[?&]updated=/)||(a+="&updated=1"),a+=location.hash,location.assign(a)},as3cf.showSettingsSavedNotice=function(){if(!(0<a("#setting-error-settings_updated:visible").length||0<a("#as3cf-settings_updated:visible").length)){var b='<div id="as3cf-settings_updated" class="updated settings-error notice is-dismissible"><p><strong>'+as3cf.strings.settings_saved+"</strong></p></div>";a("h2.nav-tab-wrapper").after(b),a(document).trigger("wp-updates-notice-added")}};var r=function(){this.$key=q.find('input[name="aws-access-key-id"]'),this.$secret=q.find('input[name="aws-secret-access-key"]'),this.$spinner=q.find("[data-as3cf-aws-keys-spinner]"),this.$feedback=q.find("[data-as3cf-aws-keys-feedback]")};r.prototype.set=function(){this.sendRequest("set",{"aws-access-key-id":this.$key.val(),"aws-secret-access-key":this.$secret.val()}).done(function(a){a.success&&this.$secret.val(as3cf.strings.not_shown_placeholder)}.bind(this))},r.prototype.remove=function(){this.sendRequest("remove").done(function(a){a.success&&(this.$key.val(""),this.$secret.val(""))}.bind(this))},r.prototype.sendRequest=function(b,c){var d={action:"as3cf-aws-keys-"+b,_ajax_nonce:as3cf.nonces["aws_keys_"+b]};return _.isObject(c)&&(d=_.extend(d,c)),this.$spinner.addClass("is-active"),a.post(ajaxurl,d).done(function(a){this.$feedback.toggleClass("notice-success",a.success).toggleClass("notice-error",!a.success),a.data&&a.data.message&&this.$feedback.html("<p>"+a.data.message+"</p>").show(),a.success&&as3cf.reloadUpdated()}.bind(this)).always(function(){this.$spinner.removeClass("is-active")}.bind(this))},a(document).ready(function(){j(),window.onhashchange=function(a){"function"==typeof history.replaceState&&"#"===location.href.slice(-1)&&history.replaceState({},"",location.href.slice(0,-1)),j()};var m=a(".as3cf-main .nav-tab-wrapper");a(".as3cf-compatibility-notice, div.updated, div.error, div.notice").not(".below-h2, .inline").insertAfter(m),p.length&&p.each(function(a,b){l[b.id]=c(b.id)}),a(window).on("beforeunload.as3cf-settings",function(){if(!a.isEmptyObject(l)){var b=k.attr("id");return c(b)!==l[b]?as3cf.strings.save_alert:void 0}}),a(document).on("submit",".as3cf-main-settings form",function(b){a(window).off("beforeunload.as3cf-settings")}),a(".as3cf-switch").on("click",function(b){a(this).hasClass("disabled")||d(a(this).attr("id"))}),p.on("change",".sub-toggle",function(b){var c=a(this).attr("id");a(".as3cf-setting."+c).toggleClass("hide")}),a(".as3cf-domain").on("change",'input[type="radio"]',function(b){var c=a(this).closest('input:radio[name="domain"]:checked'),d=c.val(),e=a(this).parents(".as3cf-domain").find(".as3cf-setting.cloudfront"),f="cloudfront"===d;e.toggleClass("hide",!f)}),a(".url-preview").on("change","input",function(a){g()}),h(),a("#as3cf-serve-from-s3,#as3cf-remove-local-file").on("change",function(a){h()}),i(),a("#as3cf-remove-local-file").on("change",function(a){i()}),a('.as3cf-setting input[type="text"]').keypress(function(a){if(13===a.which)return a.preventDefault(),!1}),a('input[name="cloudfront"]').on("keyup",function(b){e(a(this))}),a('input[name="domain"]').on("change",function(b){var c=a(this),d=a("#"+k.attr("id")+' form button[type="submit"]');"cloudfront"!==c.val()?d.prop("disabled",!1):e(c.next(".as3cf-setting").find('input[name="cloudfront"]'))}),a('input[name="object-prefix"]').on("change",function(a){f()}),a("#tab-media > .as3cf-bucket-error").detach().insertAfter(".as3cf-bucket-container h3"),o.on("click",".bucket-action-manual",function(c){c.preventDefault(),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-manual").show().siblings().hide()}),o.on("click",".bucket-action-browse",function(c){c.preventDefault(),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-select").show().siblings().hide(),as3cf.buckets.loadList(n),n=!1}),o.on("click",".bucket-action-create",function(c){c.preventDefault(),a(".as3cf-bucket-name").val(""),a(".as3cf-invalid-bucket-name").html(""),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-create").show().siblings().hide()}),o.on("click",".bucket-action-cancel",function(a){a.preventDefault(),as3cf.buckets.resetModal()}),o.on("click",".bucket-action-save",function(a){a.preventDefault(),as3cf.buckets.saveManual()}),o.on("click",'.as3cf-create-bucket-form button[type="submit"]',function(a){a.preventDefault(),as3cf.buckets.create()}),o.on("click",".bucket-action-refresh",function(a){a.preventDefault(),as3cf.buckets.loadList(!0)}),o.on("click",".as3cf-bucket-list a",function(b){b.preventDefault(),as3cf.buckets.saveSelected(a(this))}),a(".as3cf-bucket-container").on("click","a.js-link",function(b){return b.preventDefault(),window.open(a(this).attr("href")),!1}),o.on("as3cf-modal-open",function(c,d){if(".as3cf-bucket-container."+b.prefix===d){as3cf.buckets.resetModal();var e=a(".as3cf-bucket-manual h3").data("modal-title");a(".as3cf-bucket-manual h3").text(e),as3cf.buckets.disabledButtons()}}),as3cf.buckets.disabledButtons(),o.on("input keyup",".as3cf-create-bucket-form .as3cf-bucket-name",function(c){var d=a(this).val(),e=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form");as3cf.buckets.isValidName(d)?e.find("button[type=submit]").prop("disabled",!1):e.find("button[type=submit]").prop("disabled",!0),as3cf.buckets.updateNameNotice(d)}),o.on("input keyup",".as3cf-manual-save-bucket-form .as3cf-bucket-name",function(c){var d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");d.find(".as3cf-bucket-name").val().length<as3cf.buckets.validLength?d.find("button[type=submit]").prop("disabled",!0):d.find("button[type=submit]").prop("disabled",!1)}),q.on("click","[data-as3cf-toggle-access-keys-form]",function(b){b.preventDefault(),a("#as3cf_access_keys").toggle()}).on("click","[data-as3cf-aws-keys-action]",function(b){b.preventDefault();var c=a(this).data("as3cfAwsKeysAction"),d=new r;"function"==typeof d[c]&&d[c]()})})}(jQuery,as3cfModal);
1
+ !function(a,b){function c(b){return a("#"+b+" .as3cf-main-settings form").find("input:not(.no-compare)").serialize()}function d(a){var b=k.find("#"+a),c=b.find("input[type=checkbox]");b.toggleClass("on").find("span").toggleClass("checked");var d=b.find("span.on").hasClass("checked");c.prop("checked",d).trigger("change")}function e(b){var c=b.next(".as3cf-validation-error"),d=a("#"+k.attr("id")+' form button[type="submit"]'),e=/[^a-zA-Z0-9\.\-]/;e.test(b.val())?(c.show(),d.prop("disabled",!0)):(c.hide(),d.prop("disabled",!1))}function f(){var c=a("#"+b.prefix+"-bucket").val(),d=k.find('input[name="object-prefix"]'),e=d.val();""!==e&&(e=as3cf.aws_bucket_link_param+encodeURIComponent(e));var f=as3cf.aws_bucket_link+c+e;a("#"+b.prefix+"-view-bucket").attr("href",f)}function g(){a(".as3cf-url-preview").html("Generating...");var b={_nonce:as3cf.nonces.get_url_preview};a.each(a("#tab-"+as3cf.tabs.defaultTab+" .as3cf-main-settings form").serializeArray(),function(c,d){var e=d.name,f=d.value;e=e.replace("[]",""),b[e]=void 0===b[e]?f:a.isArray(b[e])?b[e].concat(f):[b[e],f]}),b.action="as3cf-get-url-preview",a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:b,error:function(a,b,c){alert(as3cf.strings.get_url_preview_error+c)},success:function(b,c,d){"undefined"!=typeof b.success?a(".as3cf-url-preview").html(b.url):alert(as3cf.strings.get_url_preview_error+b.error)}})}function h(){a("#as3cf-remove-local-file").is(":checked")&&a("#as3cf-serve-from-s3").is(":not(:checked)")?a("#as3cf-lost-files-notice").show():a("#as3cf-lost-files-notice").hide()}function i(){a("#as3cf-remove-local-file").is(":checked")?a("#as3cf-remove-local-notice").show():a("#as3cf-remove-local-notice").hide()}function j(){return"#"+as3cf.tabs.defaultTab===location.hash?void(location.hash=""):(as3cf.tabs.toggle(location.hash.replace("#",""),!0),void a(document).trigger("as3cf.tabRendered",[location.hash.replace("#","")]))}var k,l={},m=/[^a-z0-9.-]/,n=!1,o=a("body"),p=a(".as3cf-tab"),q=a(".as3cf-settings");as3cf.tabs={defaultTab:"media",toggle:function(c,d){c=as3cf.tabs.sanitizeHash(c),p.hide(),k=a("#tab-"+c),k.show(),a(".nav-tab").removeClass("nav-tab-active"),a('a.nav-tab[data-tab="'+c+'"]').addClass("nav-tab-active"),a(".as3cf-main").data("tab",c),k.data("prefix")&&(b.prefix=k.data("prefix")),d||a(".as3cf-updated").removeClass("show"),"support"===c&&as3cf.tabs.getDiagnosticInfo()},getDiagnosticInfo:function(){var b=a(".debug-log-textarea");b.html(as3cf.strings.get_diagnostic_info);var c={action:"as3cf-get-diagnostic-info",_nonce:as3cf.nonces.get_diagnostic_info};a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:c,error:function(a,c,d){b.html(d)},success:function(a,c,d){"undefined"!=typeof a.success?b.html(a.diagnostic_info):(b.html(as3cf.strings.get_diagnostic_info_error),b.append(a.error))}})},sanitizeHash:function(b){var c=a("#tab-"+b);return 0===c.length&&(b=as3cf.tabs.defaultTab),b}},as3cf.buckets={validLength:3,bucketSelectLock:!1,loadList:function(c){"undefined"==typeof c&&(c=!1);var d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-list"),e=a("#"+b.prefix+"-bucket").val();if(!1===c&&d.find("li").length>1)return a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected"),void this.scrollToSelected();d.html('<li class="loading">'+d.data("working")+"</li>");var f={action:b.prefix+"-get-buckets",_nonce:window[b.prefix.replace(/-/g,"_")].nonces.get_buckets},g=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:f,error:function(a,b,c){d.html(""),g.showError(as3cf.strings.get_buckets_error,c,"as3cf-bucket-select")},success:function(b,c,f){d.html(""),"undefined"!=typeof b.success?(a(".as3cf-bucket-error").hide(),a(b.buckets).each(function(a,b){var c=b.Name===e?"selected":"";d.append('<li><a class="'+c+'" href="#" data-bucket="'+b.Name+'"><span class="bucket"><span class="dashicons dashicons-portfolio"></span> '+b.Name+'</span><span class="spinner"></span></span></a></li>')}),g.scrollToSelected()):g.showError(as3cf.strings.get_buckets_error,b.error,"as3cf-bucket-select")}})},scrollToSelected:function(){if(a(".as3cf-bucket-list a.selected").length){var b=a("ul.as3cf-bucket-list li").first().position().top+150;a(".as3cf-bucket-list").animate({scrollTop:a("ul.as3cf-bucket-list li a.selected").position().top-b})}},resetModal:function(){var c=a(".as3cf-bucket-container."+b.prefix);!1===k.hasClass("as3cf-has-bucket")||"manual"===a("#"+b.prefix+"-bucket-select").val()?(c.find(".as3cf-bucket-manual").show().siblings().hide(),c.find(".bucket-actions.manual").show().siblings(".bucket-actions").hide()):(c.find(".as3cf-bucket-select").show().siblings().hide(),c.find(".bucket-actions.select").show().siblings(".bucket-actions").hide(),this.loadList(n),n=!1),c.find(".as3cf-bucket-error").hide();var d=a("#"+b.prefix+"-bucket").val();c.find(".as3cf-bucket-manual .as3cf-bucket-name").val(d),this.bucketSelectLock=!1},saveManual:function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),d=c.find(".as3cf-bucket-name"),e=c.find("button[type=submit]"),f=d.val(),g=e.first().text();if(f===a("#"+b.prefix+"-active-bucket").text())return a(".as3cf-bucket-error").hide(),k.addClass("as3cf-has-bucket"),void b.close();a(".as3cf-bucket-error").hide(),e.text(e.data("working")),e.prop("disabled",!0);var h={action:b.prefix+"-manual-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.manual_bucket},i=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:h,error:function(a,b,c){e.text(g),i.showError(as3cf.strings.save_bucket_error,c,"as3cf-bucket-manual")},success:function(c,d,h){e.text(g),e.prop("disabled",!1),"undefined"!=typeof c.success?(i.set(f,c.region,c.can_write),a("#"+b.prefix+"-bucket-select").val("manual"),a(".as3cf-bucket-list a").removeClass("selected").filter('[data-bucket="'+f+'"]').addClass("selected"),n=!0,as3cf.showSettingsSavedNotice()):i.showError(as3cf.strings.save_bucket_error,c.error,"as3cf-bucket-manual")}})},saveSelected:function(c){var d=a(".as3cf-bucket-list");if(!this.bucketSelectLock){if(this.bucketSelectLock=!0,c.hasClass("selected"))return k.addClass("as3cf-has-bucket"),void b.close();var e=a(".as3cf-bucket-list a.selected").data("bucket");a(".as3cf-bucket-list a").removeClass("selected"),c.addClass("selected"),d.addClass("saving"),c.find(".spinner").show().css("visibility","visible");var f=c.data("bucket"),g={action:b.prefix+"-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.save_bucket},h=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:g,error:function(b,c,f){d.removeClass("saving"),h.showError(as3cf.strings.save_bucket_error,f,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected")},success:function(g,i,j){c.find(".spinner").hide().css("visibility","hidden"),d.removeClass("saving"),"undefined"!=typeof g.success?(h.set(f,g.region,g.can_write),a("#"+b.prefix+"-bucket-select").val(""),as3cf.showSettingsSavedNotice()):(h.showError(as3cf.strings.save_bucket_error,g.error,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected"))}})}},disabledButtons:function(){if(0!==a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form").length){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form"),d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");c.find(".as3cf-bucket-name").val().length<3?c.find("button[type=submit]").prop("disabled",!0):c.find("button[type=submit]").prop("disabled",!1),d.find(".as3cf-bucket-name").val().length<3?d.find("button[type=submit]").prop("disabled",!0):d.find("button[type=submit]").prop("disabled",!1)}},showError:function(b,c,d){var e=a(".as3cf-bucket-container").children(":visible"),f=e.find(".as3cf-bucket-error");d="undefined"==typeof d?null:d,d&&!e.hasClass(d)||(f.find("span.title").html(b+" &mdash;"),f.find("span.message").html(c),f.show(),this.bucketSelectLock=!1)},set:function(e,h,i){var j=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),m=a("#"+b.prefix+"-active-bucket");if("as3cf"===b.prefix&&0===m.text().trim().length){d("as3cf-copy-to-s3-wrap"),d("as3cf-serve-from-s3-wrap");var n=k.attr("id");l[n]=c(n)}a(".as3cf-error.fatal").hide(),m.text(e),j.find(".as3cf-bucket-name").val(e),a("#"+b.prefix+"-bucket").val(e),a("#"+b.prefix+"-region").val(h),a(".updated").not(".as3cf-notice").show(),k.addClass("as3cf-has-bucket"),k.find(".as3cf-can-write-error").toggle(!i),k.find(".as3cf-bucket-error").hide(),"as3cf"===b.prefix&&g(),f(),b.close(function(){k.trigger("bucket-change",[i]),as3cf.buckets.bucketSelectLock=!1})},create:function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form"),d=c.find(".as3cf-bucket-name"),e=c.find(".bucket-create-region"),f=c.find("button[type=submit]"),g=d.val(),h=f.text();a(".as3cf-bucket-error").hide(),f.text(f.data("working")),f.prop("disabled",!0);var i={action:b.prefix+"-create-bucket",bucket_name:g,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.create_bucket};e.val()&&(i.region=e.val());var j=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:i,error:function(a,b,c){f.text(h),j.showError(as3cf.strings.create_bucket_error,c,"as3cf-bucket-create")},success:function(b,c,e){f.text(h),f.prop("disabled",!1),"undefined"!=typeof b.success?(j.set(g,b.region,b.can_write),a(".as3cf-bucket-select-region").hide(),a(".as3cf-bucket-select-region").prop("selected",!1),d.val(""),f.prop("disabled",!0),n=!0,as3cf.showSettingsSavedNotice()):j.showError(as3cf.strings.create_bucket_error,b.error,"as3cf-bucket-create")}})},isValidName:function(a){return!(a.length<3||a.length>63)&&!0!==m.test(a)},updateNameNotice:function(b){var c=null;!0===m.test(b)?c=as3cf.strings.create_bucket_invalid_chars:b.length<3?c=as3cf.strings.create_bucket_name_short:b.length>63&&(c=as3cf.strings.create_bucket_name_long),c&&b.length>0?a(".as3cf-invalid-bucket-name").html(c):a(".as3cf-invalid-bucket-name").html("")}},as3cf.reloadUpdated=function(){var a=location.pathname+location.search;location.search.match(/[?&]updated=/)||(a+="&updated=1"),a+=location.hash,location.assign(a)},as3cf.showSettingsSavedNotice=function(){if(!(0<a("#setting-error-settings_updated:visible").length||0<a("#as3cf-settings_updated:visible").length)){var b='<div id="as3cf-settings_updated" class="updated settings-error notice is-dismissible"><p><strong>'+as3cf.strings.settings_saved+"</strong></p></div>";a("h2.nav-tab-wrapper").after(b),a(document).trigger("wp-updates-notice-added")}};var r=function(){this.$key=q.find('input[name="aws-access-key-id"]'),this.$secret=q.find('input[name="aws-secret-access-key"]'),this.$spinner=q.find("[data-as3cf-aws-keys-spinner]"),this.$feedback=q.find("[data-as3cf-aws-keys-feedback]")};r.prototype.set=function(){this.sendRequest("set",{"aws-access-key-id":this.$key.val(),"aws-secret-access-key":this.$secret.val()}).done(function(a){a.success&&this.$secret.val(as3cf.strings.not_shown_placeholder)}.bind(this))},r.prototype.remove=function(){this.sendRequest("remove").done(function(a){a.success&&(this.$key.val(""),this.$secret.val(""))}.bind(this))},r.prototype.sendRequest=function(b,c){var d={action:"as3cf-aws-keys-"+b,_ajax_nonce:as3cf.nonces["aws_keys_"+b]};return _.isObject(c)&&(d=_.extend(d,c)),this.$spinner.addClass("is-active"),a.post(ajaxurl,d).done(function(a){this.$feedback.toggleClass("notice-success",a.success).toggleClass("notice-error",!a.success),a.data&&a.data.message&&this.$feedback.html("<p>"+a.data.message+"</p>").show(),a.success&&as3cf.reloadUpdated()}.bind(this)).always(function(){this.$spinner.removeClass("is-active")}.bind(this))},a(document).ready(function(){j(),window.onhashchange=function(a){"function"==typeof history.replaceState&&"#"===location.href.slice(-1)&&history.replaceState({},"",location.href.slice(0,-1)),j()};var m=a(".as3cf-main .nav-tab-wrapper");a(".as3cf-compatibility-notice, div.updated, div.error, div.notice").not(".below-h2, .inline").insertAfter(m),p.length&&p.each(function(a,b){l[b.id]=c(b.id)}),a(window).on("beforeunload.as3cf-settings",function(){if(!a.isEmptyObject(l)){var b=k.attr("id");return c(b)!==l[b]?as3cf.strings.save_alert:void 0}}),a(document).on("submit",".as3cf-main-settings form",function(b){a(window).off("beforeunload.as3cf-settings")}),a(".as3cf-switch").on("click",function(b){a(this).hasClass("disabled")||d(a(this).attr("id"))}),p.on("change",".sub-toggle",function(b){var c=a(this).attr("id");a(".as3cf-setting."+c).toggleClass("hide")}),a(".as3cf-domain").on("change",'input[type="radio"]',function(b){var c=a(this).closest('input:radio[name="domain"]:checked'),d=c.val(),e=a(this).parents(".as3cf-domain").find(".as3cf-setting.cloudfront"),f="cloudfront"===d;e.toggleClass("hide",!f)}),a(".url-preview").on("change","input",function(a){g()}),h(),a("#as3cf-serve-from-s3,#as3cf-remove-local-file").on("change",function(a){h()}),i(),a("#as3cf-remove-local-file").on("change",function(a){i()}),a('.as3cf-setting input[type="text"]').keypress(function(a){if(13===a.which)return a.preventDefault(),!1}),a('input[name="cloudfront"]').on("keyup",function(b){e(a(this))}),a('input[name="domain"]').on("change",function(b){var c=a(this),d=a("#"+k.attr("id")+' form button[type="submit"]');"cloudfront"!==c.val()?d.prop("disabled",!1):e(c.next(".as3cf-setting").find('input[name="cloudfront"]'))}),a('input[name="object-prefix"]').on("change",function(a){f()}),a("#tab-media > .as3cf-bucket-error").detach().insertAfter(".as3cf-bucket-container h3"),o.on("click",".bucket-action-manual",function(c){c.preventDefault(),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-manual").show().siblings().hide()}),o.on("click",".bucket-action-browse",function(c){c.preventDefault(),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-select").show().siblings().hide(),as3cf.buckets.loadList(n),n=!1}),o.on("click",".bucket-action-create",function(c){c.preventDefault(),a(".as3cf-bucket-name").val(""),a(".as3cf-invalid-bucket-name").html(""),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-create").show().siblings().hide()}),o.on("click",".bucket-action-cancel",function(a){a.preventDefault(),as3cf.buckets.resetModal()}),o.on("click",".bucket-action-save",function(a){a.preventDefault(),as3cf.buckets.saveManual()}),o.on("click",'.as3cf-create-bucket-form button[type="submit"]',function(a){a.preventDefault(),as3cf.buckets.create()}),o.on("click",".bucket-action-refresh",function(a){a.preventDefault(),as3cf.buckets.loadList(!0)}),o.on("click",".as3cf-bucket-list a",function(b){b.preventDefault(),as3cf.buckets.saveSelected(a(this))}),a(".as3cf-bucket-container").on("click","a.js-link",function(b){return b.preventDefault(),window.open(a(this).attr("href")),!1}),o.on("as3cf-modal-open",function(c,d){if(".as3cf-bucket-container."+b.prefix===d){as3cf.buckets.resetModal();var e=a(".as3cf-bucket-manual h3").data("modal-title");a(".as3cf-bucket-manual h3").text(e),as3cf.buckets.disabledButtons()}}),as3cf.buckets.disabledButtons(),o.on("input keyup",".as3cf-create-bucket-form .as3cf-bucket-name",function(c){var d=a(this).val(),e=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form");as3cf.buckets.isValidName(d)?e.find("button[type=submit]").prop("disabled",!1):e.find("button[type=submit]").prop("disabled",!0),as3cf.buckets.updateNameNotice(d)}),o.on("input keyup",".as3cf-manual-save-bucket-form .as3cf-bucket-name",function(c){var d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");d.find(".as3cf-bucket-name").val().length<as3cf.buckets.validLength?d.find("button[type=submit]").prop("disabled",!0):d.find("button[type=submit]").prop("disabled",!1)}),q.on("click","[data-as3cf-toggle-access-keys-form]",function(b){b.preventDefault(),a("#as3cf_access_keys").toggle()}).on("click","[data-as3cf-aws-keys-action]",function(b){b.preventDefault();var c=a(this).data("as3cfAwsKeysAction"),d=new r;"function"==typeof d[c]&&d[c]()})})}(jQuery,as3cfModal);
classes/amazon-s3-and-cloudfront.php CHANGED
@@ -1,8 +1,8 @@
1
  <?php
2
 
3
- use DeliciousBrains\WP_Offload_S3\Aws2\Aws\S3\S3Client;
4
- use DeliciousBrains\WP_Offload_S3\Null_S3_Client;
5
- use DeliciousBrains\WP_Offload_S3\Amazon_Web_Services;
6
  use DeliciousBrains\WP_Offload_S3\Upgrades\Upgrade_Content_Replace_URLs;
7
  use DeliciousBrains\WP_Offload_S3\Upgrades\Upgrade_EDD_Replace_URLs;
8
  use DeliciousBrains\WP_Offload_S3\Upgrades\Upgrade_File_Sizes;
@@ -13,12 +13,12 @@ use DeliciousBrains\WP_Offload_S3\Upgrades\Upgrade_Region_Meta;
13
  class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
14
 
15
  /**
16
- * @var Amazon_Web_Services
17
  */
18
  private $aws;
19
 
20
  /**
21
- * @var S3Client
22
  */
23
  private $s3client;
24
 
@@ -82,12 +82,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
82
  */
83
  public $plugin_compat;
84
 
85
- const DEFAULT_ACL = 'public-read';
86
- const PRIVATE_ACL = 'private';
87
  const DEFAULT_EXPIRES = 900;
88
- const DEFAULT_REGION = 'us-east-1';
89
- const AWS_SIGNATURE = 'v4';
90
- const S3_API_VERSION = '2006-03-01';
91
 
92
  const SETTINGS_KEY = 'tantan_wordpress_s3';
93
  const SETTINGS_CONSTANT = 'WPOS3_SETTINGS';
@@ -95,20 +90,16 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
95
  const LATEST_UPGRADE_ROUTINE = 6;
96
 
97
  /**
98
- * @param string $plugin_file_path
99
- * @param Amazon_Web_Services|null $aws
100
- * @param string|null $slug
 
101
  */
102
- function __construct( $plugin_file_path, $aws = null, $slug = null ) {
103
  $this->plugin_slug = ( is_null( $slug ) ) ? 'amazon-s3-and-cloudfront' : $slug;
104
 
105
  parent::__construct( $plugin_file_path );
106
 
107
- if ( is_null( $aws ) ) {
108
- $this->aws = new \DeliciousBrains\WP_Offload_S3\Amazon_Web_Services( $plugin_file_path );
109
- } else {
110
- $this->aws = $aws;
111
- }
112
  $this->notices = AS3CF_Notices::get_instance( $this );
113
 
114
  $this->init( $plugin_file_path );
@@ -123,6 +114,8 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
123
  $this->plugin_title = __( 'Offload S3', 'amazon-s3-and-cloudfront' );
124
  $this->plugin_menu_title = __( 'Offload S3', 'amazon-s3-and-cloudfront' );
125
 
 
 
126
  // Bundled SDK may require AWS setup before data migrations.
127
  $this->handle_aws_access_key_migration();
128
 
@@ -194,12 +187,21 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
194
  }
195
 
196
  /**
197
- * @return Amazon_Web_Services
198
  */
199
  public function get_aws() {
200
  return $this->aws;
201
  }
202
 
 
 
 
 
 
 
 
 
 
203
  /**
204
  * Get the plugin title to be used in page headings
205
  *
@@ -285,8 +287,8 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
285
 
286
  // If legacy setting set, migrate settings
287
  if ( isset( $settings['wp-uploads'] ) &&
288
- $settings['wp-uploads'] &&
289
- in_array( $key, array( 'copy-to-s3', 'serve-from-s3', ) )
290
  ) {
291
  return '1';
292
  }
@@ -426,8 +428,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
426
 
427
  // Region of bucket translation
428
  if ( 'region' === $key && isset( $settings['region'] ) ) {
429
-
430
- return $this->translate_region( $settings['region'] );
431
  }
432
 
433
  return false;
@@ -781,7 +782,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
781
  'message' => __( 'Access keys updated successfully.', 'amazon-s3-and-cloudfront' ),
782
  );
783
 
784
- if ( Amazon_Web_Services::is_any_access_key_constant_defined() ) {
785
  wp_send_json_error( array(
786
  'message' => __( 'All access key constants must be removed before keys can be set in the database.', 'amazon-s3-and-cloudfront' ),
787
  ) );
@@ -829,7 +830,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
829
  * Remove AWS access keys from saved settings if a key constant is defined.
830
  */
831
  public function remove_aws_keys_if_constants_set() {
832
- if ( Amazon_Web_Services::is_any_access_key_constant_defined() ) {
833
  $this->remove_aws_keys();
834
  }
835
  }
@@ -861,7 +862,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
861
 
862
  try {
863
  foreach ( $chunks as $chunk ) {
864
- $this->get_s3client( $region, $force_new_s3_client )->deleteObjects( array(
865
  'Bucket' => $bucket,
866
  'Objects' => $chunk,
867
  ) );
@@ -1025,7 +1026,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1025
  return $this->return_upload_error( $error_msg, $return_metadata );
1026
  }
1027
 
1028
- $acl = self::DEFAULT_ACL;
1029
 
1030
  // check the attachment already exists in S3, eg. edit or restore image
1031
  if ( ( $old_s3object = $this->get_attachment_s3_info( $post_id ) ) ) {
@@ -1089,7 +1090,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1089
  );
1090
 
1091
  // Do not store object ACL if set to the default value.
1092
- if ( $s3object['acl'] === self::DEFAULT_ACL ) {
1093
  unset( $s3object['acl'] );
1094
  }
1095
 
@@ -1100,7 +1101,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1100
  $s3client = $this->get_s3client( $s3object['region'], $force_new_s3_client );
1101
 
1102
  try {
1103
- $s3client->putObject( $args );
1104
  $files_to_remove[] = $file_path;
1105
  } catch ( Exception $e ) {
1106
  $error_msg = sprintf( __( 'Error uploading %s to S3: %s', 'amazon-s3-and-cloudfront' ), $file_path, $e->getMessage() );
@@ -1114,31 +1115,11 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1114
 
1115
  $file_paths = AS3CF_Utils::get_attachment_file_paths( $post_id, false, $data );
1116
  $additional_images = array();
1117
-
1118
- $filesize_total = 0;
1119
- $remove_local_files_setting = $this->get_setting( 'remove-local-file' );
1120
-
1121
- if ( $remove_local_files_setting ) {
1122
- $bytes = filesize( $file_path );
1123
- if ( false !== $bytes ) {
1124
- // Store in the attachment meta data for use by WP
1125
- $data['filesize'] = $bytes;
1126
-
1127
- if ( is_null( $return_metadata ) ) {
1128
- // Update metadata with filesize
1129
- update_post_meta( $post_id, '_wp_attachment_metadata', $data );
1130
- }
1131
-
1132
- // Add to the file size total
1133
- $filesize_total += $bytes;
1134
- }
1135
- }
1136
-
1137
- $s3object_sizes = array();
1138
 
1139
  foreach ( $file_paths as $size => $file_path ) {
1140
  if ( ! in_array( $file_path, $files_to_remove ) ) {
1141
- $acl = apply_filters( 'as3cf_upload_acl_sizes', self::DEFAULT_ACL, $size, $post_id, $data );
1142
 
1143
  $additional_images[ $size ] = array(
1144
  'Key' => $prefix . wp_basename( $file_path ),
@@ -1147,17 +1128,9 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1147
  'ContentType' => $this->get_mime_type( $file_path ),
1148
  );
1149
 
1150
- if ( self::DEFAULT_ACL !== $acl ) {
1151
  $s3object_sizes[ $size ]['acl'] = $acl;
1152
  }
1153
-
1154
- if ( $remove_local_files_setting && file_exists( $file_path ) ) {
1155
- // Record the file size for the additional image
1156
- $bytes = filesize( $file_path );
1157
- if ( false !== $bytes ) {
1158
- $filesize_total += $bytes;
1159
- }
1160
- }
1161
  }
1162
  }
1163
 
@@ -1172,44 +1145,43 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1172
  }
1173
 
1174
  try {
1175
- $s3client->putObject( $args );
1176
  $files_to_remove[] = $image['SourceFile'];
1177
  } catch ( Exception $e ) {
1178
  $upload_errors[] = $this->return_upload_error( sprintf( __( 'Error uploading %s to S3: %s', 'amazon-s3-and-cloudfront' ), $args['SourceFile'], $e->getMessage() ) );
1179
  }
1180
  }
1181
 
 
 
1182
  if ( $remove_local_files ) {
1183
  if ( $remove_local_files_setting ) {
1184
  // Allow other functions to remove files after they have processed
1185
  $files_to_remove = apply_filters( 'as3cf_upload_attachment_local_files_to_remove', $files_to_remove, $post_id, $file_path );
 
1186
  // Remove duplicates
1187
  $files_to_remove = array_unique( $files_to_remove );
1188
- // Delete the files
1189
- $this->remove_local_files( $files_to_remove );
1190
- }
1191
- }
1192
 
1193
- // Store the file size in the attachment meta if we are removing local file
1194
- if ( $remove_local_files_setting ) {
1195
- if ( $filesize_total > 0 ) {
1196
- // Add the total file size for all image sizes
1197
- update_post_meta( $post_id, 'wpos3_filesize_total', $filesize_total );
1198
- }
1199
- } else {
1200
- if ( isset( $data['filesize'] ) ) {
1201
- // Make sure we don't have a cached file sizes in the meta
1202
- unset( $data['filesize'] );
1203
 
1204
- if ( is_null( $return_metadata ) ) {
1205
- // Remove the filesize from the metadata
1206
- update_post_meta( $post_id, '_wp_attachment_metadata', $data );
1207
- }
1208
 
1209
- delete_post_meta( $post_id, 'wpos3_filesize_total' );
 
 
 
 
1210
  }
1211
  }
1212
 
 
 
 
 
 
1213
  if ( ! empty( $s3object_sizes ) ) {
1214
  // Additional image sizes have custom ACLs, update meta
1215
  $s3object['sizes'] = $s3object_sizes;
@@ -1311,12 +1283,30 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1311
  }
1312
 
1313
  /**
1314
- * Remove files from the local site
1315
  *
1316
  * @param array $file_paths array of files to remove
 
 
 
1317
  */
1318
- function remove_local_files( $file_paths ) {
1319
- foreach ( $file_paths as $path ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1320
  if ( false !== ( $pre = apply_filters( 'as3cf_preserve_file_from_local_removal', false, $path ) ) ) {
1321
  continue;
1322
  }
@@ -1333,6 +1323,13 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1333
  AS3CF_Error::log( $message . $path );
1334
  }
1335
  }
 
 
 
 
 
 
 
1336
  }
1337
 
1338
  /**
@@ -1364,6 +1361,10 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1364
  * @return null|string
1365
  */
1366
  function get_folder_time_from_url( $url ) {
 
 
 
 
1367
  preg_match( '@[0-9]{4}/[0-9]{2}@', $url, $matches );
1368
 
1369
  if ( isset( $matches[0] ) ) {
@@ -1557,7 +1558,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1557
  $prefix = AS3CF_Utils::trailingslash_prefix( $this->get_object_prefix() );
1558
  $prefix .= AS3CF_Utils::trailingslash_prefix( $this->get_dynamic_prefix( $time ) );
1559
 
1560
- return $s3client->doesObjectExist( $bucket, $prefix . $filename );
1561
  }
1562
 
1563
  /**
@@ -1608,7 +1609,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1608
  * @return bool
1609
  */
1610
  function is_plugin_setup( $with_credentials = false ) {
1611
- if ( $with_credentials && $this->aws->needs_access_keys() ) {
1612
  // AWS not configured
1613
  return false;
1614
  }
@@ -1742,7 +1743,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1742
  $prefix .= $delimiter . $region;
1743
  }
1744
 
1745
- return $prefix;
1746
  }
1747
 
1748
  /**
@@ -1754,7 +1755,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1754
  * @param array $args Allows you to specify custom URL settings
1755
  * @param bool $preview When generating the URL preview sanitize certain output
1756
  *
1757
- * @return mixed|string|void
1758
  */
1759
  function get_s3_url_domain( $bucket, $region = '', $expires = null, $args = array(), $preview = false ) {
1760
  if ( ! isset( $args['cloudfront'] ) ) {
@@ -1769,7 +1770,10 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1769
  $args['force-https'] = $this->get_setting( 'force-https' );
1770
  }
1771
 
1772
- $prefix = $this->get_s3_url_prefix( $region, $expires );
 
 
 
1773
 
1774
  if ( 'cloudfront' === $args['domain'] && is_null( $expires ) && $args['cloudfront'] ) {
1775
  $cloudfront = $args['cloudfront'];
@@ -1781,9 +1785,9 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1781
  } elseif ( 'virtual-host' === $args['domain'] ) {
1782
  $s3_domain = $bucket;
1783
  } elseif ( 'path' === $args['domain'] || $this->use_ssl( $args['force-https'] ) ) {
1784
- $s3_domain = $prefix . '.amazonaws.com/' . $bucket;
1785
  } else {
1786
- $s3_domain = $bucket . '.' . $prefix . '.amazonaws.com';
1787
  }
1788
 
1789
  return $s3_domain;
@@ -1895,8 +1899,8 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1895
 
1896
  // We don't use $this->get_s3object_region() here because we don't want
1897
  // to make an AWS API call and slow down page loading
1898
- if ( isset( $s3object['region'] ) && self::DEFAULT_REGION !== $s3object['region'] ) {
1899
- $region = $this->translate_region( $s3object['region'] );
1900
  } else {
1901
  $region = '';
1902
  }
@@ -1905,12 +1909,12 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1905
 
1906
  // Force use of secured URL when ACL has been set to private
1907
  if ( is_null( $expires ) ) {
1908
- if ( is_null( $size ) && isset( $s3object['acl'] ) && self::PRIVATE_ACL === $s3object['acl'] ) {
1909
  // Full size URL private
1910
  $expires = self::DEFAULT_EXPIRES;
1911
  }
1912
 
1913
- if ( ! is_null( $size ) && isset( $s3object['sizes'][ $size ]['acl'] ) && self::PRIVATE_ACL === $s3object['sizes'][ $size ]['acl'] ) {
1914
  // Alternative size URL private
1915
  $expires = self::DEFAULT_EXPIRES;
1916
  }
@@ -1937,7 +1941,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1937
  try {
1938
  $expires = time() + apply_filters( 'as3cf_expires', $expires );
1939
  $secure_url = $this->get_s3client( $region )
1940
- ->getObjectUrl( $s3object['bucket'], $s3object['key'], $expires, $headers );
1941
 
1942
  return apply_filters( 'as3cf_get_attachment_secure_url', $secure_url, $s3object, $post_id, $expires, $headers );
1943
  } catch ( Exception $e ) {
@@ -1993,6 +1997,10 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
1993
  return $html;
1994
  }
1995
 
 
 
 
 
1996
  preg_match( '@\ssrc=[\'\"]([^\'\"]*)[\'\"]@', $html, $matches );
1997
 
1998
  if ( ! isset( $matches[1] ) ) {
@@ -2319,14 +2327,36 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2319
  wp_send_json( $return );
2320
  }
2321
 
2322
- function verify_ajax_request() {
2323
- if ( ! is_admin() || ! wp_verify_nonce( sanitize_key( $_POST['_nonce'] ), sanitize_key( $_POST['action'] ) ) ) { // input var okay
2324
- wp_die( __( 'Cheatin&#8217; eh?', 'amazon-s3-and-cloudfront' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2325
  }
2326
 
2327
- if ( ! current_user_can( 'manage_options' ) ) {
2328
- wp_die( __( 'You do not have sufficient permissions to access this page.', 'amazon-s3-and-cloudfront' ) );
 
 
 
 
 
 
2329
  }
 
 
2330
  }
2331
 
2332
  function ajax_check_bucket() {
@@ -2389,11 +2419,11 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2389
  $region = AS3CF_REGION;
2390
  }
2391
 
2392
- if ( ! is_null( $region ) && self::DEFAULT_REGION !== $region ) {
2393
  $args['LocationConstraint'] = $region;
2394
  }
2395
 
2396
- $this->get_s3client()->createBucket( $args );
2397
  } catch ( Exception $e ) {
2398
  return new WP_Error( 'exception', $e->getMessage() );
2399
  }
@@ -2507,7 +2537,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2507
  }
2508
  }
2509
 
2510
- if ( self::DEFAULT_REGION === $region ) {
2511
  $region = '';
2512
  }
2513
 
@@ -2561,37 +2591,45 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2561
  );
2562
  }
2563
 
 
 
 
 
 
 
 
 
 
2564
  /**
2565
  * Get the S3 client
2566
  *
2567
  * @param bool|string $region specify region to client for signature
2568
  * @param bool $force force return of new S3 client when swapping regions
2569
  *
2570
- * @return S3Client
2571
  */
2572
  public function get_s3client( $region = false, $force = false ) {
2573
  if ( is_null( $this->s3client ) ||
2574
  is_null( $this->s3client_region ) ||
2575
  $force ||
2576
  ( false !== $region && $this->s3client_region !== $region ) ) {
 
2577
 
2578
- $args = array(
2579
- 'version' => self::S3_API_VERSION,
2580
- );
2581
 
2582
  if ( $region ) {
2583
- $args['region'] = $this->translate_region( $region );
2584
- $args['signature'] = self::AWS_SIGNATURE;
2585
  }
2586
 
2587
  $s3client_region = isset( $args['region'] ) ? $args['region'] : $region;
2588
 
2589
  try {
2590
- $aws_client = $this->aws->get_client();
2591
- $this->set_client( $aws_client->get( 's3', $args ), $s3client_region );
2592
  } catch ( \Exception $e ) {
2593
  AS3CF_Error::log( $e->getMessage() );
2594
- $this->set_client( new Null_S3_Client );
2595
  }
2596
  }
2597
 
@@ -2601,8 +2639,8 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2601
  /**
2602
  * Setter for S3 client
2603
  *
2604
- * @param Aws\S3\S3Client|Null_S3_Client $client
2605
- * @param bool|string $region
2606
  */
2607
  public function set_client( $client, $region = false ) {
2608
  $this->s3client = $client;
@@ -2632,7 +2670,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2632
  }
2633
 
2634
  try {
2635
- $region = $this->get_s3client()->getBucketLocation( array( 'Bucket' => $bucket ) );
2636
  } catch ( Exception $e ) {
2637
  $error_msg_title = '<strong>' . __( 'Error Getting Bucket Region', 'amazon-s3-and-cloudfront' ) . '</strong> &mdash;';
2638
  $error_msg = sprintf( __( 'There was an error attempting to get the region of the bucket %s: %s', 'amazon-s3-and-cloudfront' ), $bucket, $e->getMessage() );
@@ -2641,7 +2679,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2641
  return new WP_Error( 'exception', $error_msg_title . $error_msg );
2642
  }
2643
 
2644
- $region = $this->translate_region( $region['Location'] );
2645
 
2646
  if ( is_string( $region ) ) {
2647
  $regions[ $bucket ] = $region;
@@ -2679,31 +2717,6 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2679
  return $s3object['region'];
2680
  }
2681
 
2682
- /**
2683
- * Translate older bucket locations to newer S3 region names
2684
- * http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
2685
- *
2686
- * @param $region
2687
- *
2688
- * @return string
2689
- */
2690
- function translate_region( $region ) {
2691
- if ( ! is_string( $region ) ) {
2692
- // Don't translate any region errors
2693
- return $region;
2694
- }
2695
-
2696
- $region = strtolower( $region );
2697
-
2698
- switch ( $region ) {
2699
- case 'eu':
2700
- $region = 'eu-west-1';
2701
- break;
2702
- }
2703
-
2704
- return $region;
2705
- }
2706
-
2707
  /**
2708
  * AJAX handler for get_buckets()
2709
  */
@@ -2730,7 +2743,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2730
  */
2731
  function get_buckets() {
2732
  try {
2733
- $result = $this->get_s3client()->listBuckets();
2734
  } catch ( Exception $e ) {
2735
  return new WP_Error( 'exception', $e->getMessage() );
2736
  }
@@ -2747,7 +2760,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2747
  * @return bool|WP_Error
2748
  */
2749
  function check_write_permission( $bucket = null, $region = null ) {
2750
- if ( $this->aws->needs_access_keys() ) {
2751
  // If no access keys set then no need check.
2752
  return false;
2753
  }
@@ -2772,34 +2785,17 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2772
  return self::$buckets_check[ $bucket ];
2773
  }
2774
 
2775
- $key = $this->get_file_prefix() . 'as3cf-permission-check.txt';
2776
  $file_contents = __( 'This is a test file to check if the user has write permission to S3. Delete me if found.', 'amazon-s3-and-cloudfront' );
2777
 
2778
- try {
2779
- // attempt to create the test file
2780
- $this->get_s3client( $region, true )->putObject( array(
2781
- 'Bucket' => $bucket,
2782
- 'Key' => $key,
2783
- 'Body' => $file_contents,
2784
- 'ACL' => 'public-read',
2785
- ) );
2786
- // delete it straight away if created
2787
- $this->get_s3client()->deleteObject( array(
2788
- 'Bucket' => $bucket,
2789
- 'Key' => $key,
2790
- ) );
2791
- $can_write = true;
2792
- } catch ( Exception $e ) {
2793
- // if we encounter an error that isn't access denied, throw that error
2794
- if ( ! $e instanceof Aws\Common\Exception\ServiceResponseException || 'AccessDenied' !== $e->getExceptionCode() ) {
2795
- $error_msg = sprintf( __( 'There was an error attempting to check the permissions of the bucket %s: %s', 'amazon-s3-and-cloudfront' ), $bucket, $e->getMessage() );
2796
- AS3CF_Error::log( $error_msg );
2797
 
2798
- return new WP_Error( 'exception', $error_msg );
2799
- }
 
 
2800
 
2801
- // write permission not found
2802
- $can_write = false;
2803
  }
2804
 
2805
  self::$buckets_check[ $bucket ] = $can_write;
@@ -2857,7 +2853,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2857
  wp_localize_script( 'as3cf-script',
2858
  'as3cf',
2859
  array(
2860
- 'strings' => array(
2861
  'create_bucket_error' => __( 'Error creating bucket', 'amazon-s3-and-cloudfront' ),
2862
  'create_bucket_name_short' => __( 'Bucket name too short.', 'amazon-s3-and-cloudfront' ),
2863
  'create_bucket_name_long' => __( 'Bucket name too long.', 'amazon-s3-and-cloudfront' ),
@@ -2872,7 +2868,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2872
  // Mimic WP Core's notice text, therefore no translation needed here.
2873
  'settings_saved' => __( 'Settings saved.' ),
2874
  ),
2875
- 'nonces' => array(
2876
  'create_bucket' => wp_create_nonce( 'as3cf-create-bucket' ),
2877
  'manual_bucket' => wp_create_nonce( 'as3cf-manual-save-bucket' ),
2878
  'get_buckets' => wp_create_nonce( 'as3cf-get-buckets' ),
@@ -2882,8 +2878,9 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2882
  'aws_keys_set' => wp_create_nonce( 'as3cf-aws-keys-set' ),
2883
  'aws_keys_remove' => wp_create_nonce( 'as3cf-aws-keys-remove' ),
2884
  ),
2885
- 'is_pro' => $this->is_pro(),
2886
- 'aws_bucket_link' => $this->get_aws_bucket_link(),
 
2887
  )
2888
  );
2889
 
@@ -2945,7 +2942,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
2945
 
2946
  do_action( 'as3cf_pre_save_settings' );
2947
 
2948
- $post_vars = $this->get_settings_whitelist();
2949
 
2950
  foreach ( $post_vars as $var ) {
2951
  $this->remove_setting( $var );
@@ -3010,8 +3007,8 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3010
 
3011
  foreach ( $addons as $slug => $addon ) {
3012
  $this->render_view( 'addon', array(
3013
- 'slug' => $slug,
3014
- 'addon' => $addon
3015
  ) );
3016
  }
3017
  }
@@ -3168,10 +3165,19 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3168
  */
3169
  function get_aws_bucket_link( $bucket = '', $prefix = '' ) {
3170
  if ( '' !== $prefix ) {
3171
- $prefix = '&prefix=' . urlencode( $prefix );
3172
  }
3173
 
3174
- return 'https://console.aws.amazon.com/s3/home?bucket=' . $bucket . $prefix;
 
 
 
 
 
 
 
 
 
3175
  }
3176
 
3177
  /**
@@ -3199,11 +3205,11 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3199
  $s3client = $this->get_s3client( $region, true );
3200
 
3201
  try {
3202
- $s3client->PutObjectAcl( $args );
3203
  $s3object['acl'] = $acl;
3204
 
3205
  // update S3 meta data
3206
- if ( $acl == self::DEFAULT_ACL ) {
3207
  unset( $s3object['acl'] );
3208
  }
3209
 
@@ -3225,7 +3231,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3225
  */
3226
  function make_acl_admin_notice( $s3object ) {
3227
  $filename = wp_basename( $s3object['key'] );
3228
- $acl = ( isset( $s3object['acl'] ) ) ? $s3object['acl'] : self::DEFAULT_ACL;
3229
  $acl_name = $this->get_acl_display_name( $acl );
3230
  $text = sprintf( __( '<strong>WP Offload S3</strong> &mdash; The file %s has been given %s permissions on Amazon S3.', 'amazon-s3-and-cloudfront' ), "<strong>{$filename}</strong>", "<strong>{$acl_name}</strong>" );
3231
 
@@ -3419,7 +3425,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3419
  }
3420
  $output .= "\r\n";
3421
 
3422
- $output .= 'allow_url_fopen: ';
3423
  $allow_url_fopen = ini_get( 'allow_url_fopen' );
3424
  if ( empty( $allow_url_fopen ) ) {
3425
  $output .= 'Disabled';
@@ -3438,7 +3444,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3438
 
3439
  $output .= 'cURL: ';
3440
  if ( function_exists( 'curl_init' ) ) {
3441
- $curl = curl_version();
3442
  $output .= esc_html( $curl['version'] );
3443
  } else {
3444
  $output .= 'Disabled';
@@ -3456,7 +3462,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3456
  $output .= 'PHP GD: ';
3457
  if ( $this->gd_enabled() ) {
3458
  $gd_info = gd_info();
3459
- $output .= isset( $gd_info['GD Version'] ) ? esc_html( $gd_info['GD Version'] ) : 'Enabled';
3460
  } else {
3461
  $output .= 'Disabled';
3462
  }
@@ -3497,15 +3503,15 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3497
  $output .= "\r\n";
3498
 
3499
  $output .= 'Number of Image Sizes: ';
3500
- $sizes = count( get_intermediate_image_sizes() );
3501
  $output .= number_format_i18n( $sizes );
3502
  $output .= "\r\n\r\n";
3503
 
3504
- $output .= 'Names and Dimensions of Image Sizes: ';
3505
- $output .= "\r\n";
3506
  $size_details = $this->get_image_sizes_details();
3507
- $output .= $size_details;
3508
- $output .= "\r\n";
3509
 
3510
  $output .= 'WP_CONTENT_DIR: ';
3511
  $output .= esc_html( ( defined( 'WP_CONTENT_DIR' ) ) ? WP_CONTENT_DIR : 'Not defined' );
@@ -3592,21 +3598,21 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3592
  }
3593
 
3594
  $theme_info = wp_get_theme();
3595
- $output .= "Active Theme Name: " . esc_html( $theme_info->get( 'Name' ) );
3596
- $output .= "\r\n";
3597
- $output .= "Active Theme Version: " . esc_html( $theme_info->get( 'Version' ) );
3598
- $output .= "\r\n";
3599
- $output .= "Active Theme Folder: " . esc_html( $theme_info->get_stylesheet() );
3600
- $output .= "\r\n";
3601
 
3602
  if ( is_child_theme() ) {
3603
  $parent_info = $theme_info->parent();
3604
- $output .= "Parent Theme Name: " . esc_html( $parent_info->get( 'Name' ) );
3605
- $output .= "\r\n";
3606
- $output .= "Parent Theme Version: " . esc_html( $parent_info->get( 'Version' ) );
3607
- $output .= "\r\n";
3608
- $output .= "Parent Theme Folder: " . esc_html( $parent_info->get_stylesheet() );
3609
- $output .= "\r\n";
3610
  }
3611
  if ( ! file_exists( $theme_info->get_stylesheet_directory() ) ) {
3612
  $output .= "WARNING: Active Theme Folder Not Found\r\n";
@@ -3614,7 +3620,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3614
 
3615
  $output .= "\r\n";
3616
 
3617
- $output .= "Active Plugins:\r\n";
3618
  $active_plugins = (array) get_option( 'active_plugins', array() );
3619
  $plugin_details = array();
3620
 
@@ -3633,8 +3639,8 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3633
  $mu_plugins = wp_get_mu_plugins();
3634
  if ( $mu_plugins ) {
3635
  $mu_plugin_details = array();
3636
- $output .= "\r\n";
3637
- $output .= "Must-use Plugins:\r\n";
3638
 
3639
  foreach ( $mu_plugins as $mu_plugin ) {
3640
  $mu_plugin_details[] = $this->get_plugin_details( $mu_plugin );
@@ -3859,7 +3865,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3859
  * @return string
3860
  */
3861
  function get_access_denied_notice_message( $single = true ) {
3862
- if ( $this->aws->needs_access_keys() ) {
3863
  return sprintf( __( '<a href="%s">Define your AWS keys</a> to enable write access to the bucket', 'amazon-s3-and-cloudfront' ), '#settings' );
3864
  }
3865
 
@@ -3978,7 +3984,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3978
  AND pm.`meta_key` = 'amazonS3_info'";
3979
 
3980
  $operator = $uploaded_to_s3 ? 'not ' : '';
3981
- $where .= " AND pm.`post_id` is {$operator}null";
3982
  }
3983
 
3984
  $sql .= ' ' . $where;
@@ -3998,9 +4004,9 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
3998
  $all_media_s3 = 0;
3999
 
4000
  foreach ( $table_prefixes as $blog_id => $table_prefix ) {
4001
- $count = $this->count_attachments( $table_prefix );
4002
- $all_media += $count;
4003
- $s3_count = $this->count_attachments( $table_prefix, true );
4004
  $all_media_s3 += $s3_count;
4005
  }
4006
 
@@ -4170,7 +4176,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
4170
  );
4171
 
4172
  $doc_url = $this->dbrains_url( '/wp-offload-s3/doc/force-http-setting/', array(
4173
- 'utm_campaign' => 'support+docs'
4174
  ) );
4175
  $doc_link = AS3CF_Utils::dbrains_link( $doc_url, __( 'this doc' ) );
4176
 
@@ -4241,11 +4247,11 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
4241
  $file = get_attached_file( $post->ID, true );
4242
 
4243
  $args = array(
4244
- 's3object' => $this->get_formatted_s3_info( $post->ID ),
4245
- 'post' => $post,
4246
- 'local_file_exists' => file_exists( $file ),
4247
- 'available_actions' => $this->get_available_media_actions( 'singular' ),
4248
- 'sendback' => 'post.php?post=' . $post->ID . '&action=edit',
4249
  );
4250
 
4251
  $this->render_view( 'attachment-metabox', $args );
@@ -4279,23 +4285,23 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
4279
 
4280
  $s3object['url'] = $this->get_attachment_s3_url( $id, $s3object );
4281
 
4282
- $acl = ( isset( $s3object['acl'] ) ) ? $s3object['acl'] : self::DEFAULT_ACL;
4283
  $acl_info = array(
4284
  'acl' => $acl,
4285
  'name' => $this->get_acl_display_name( $acl ),
4286
  'title' => $this->get_media_action_strings( 'change_to_private' ),
4287
  );
4288
 
4289
- if ( self::PRIVATE_ACL === $acl ) {
4290
  $acl_info['title'] = $this->get_media_action_strings( 'change_to_public' );
4291
  }
4292
 
4293
  $s3object['acl'] = $acl_info;
4294
 
4295
- $regions = $this->get_aws_regions();
4296
 
4297
  if ( isset( $s3object['region'] ) && '' == $s3object['region'] ) {
4298
- $s3object['region'] = self::DEFAULT_REGION;
4299
  }
4300
 
4301
  if ( isset( $regions[ $s3object['region'] ] ) ) {
@@ -4342,11 +4348,11 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
4342
  ) );
4343
 
4344
  wp_localize_script( 'as3cf-media-script', 'as3cf_media', array(
4345
- 'strings' => $this->get_media_action_strings(),
4346
- 'nonces' => array(
4347
- 'get_attachment_s3_details' => wp_create_nonce( 'get-attachment-s3-details' ),
4348
- ),
4349
- ) );
4350
  }
4351
 
4352
  /**
@@ -4491,14 +4497,14 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
4491
  $s3_info = $this->get_attachment_s3_info( $attachment_id );
4492
 
4493
  if ( 'original' === $size || empty( $size ) ) {
4494
- return isset( $s3_info['acl'] ) ? $s3_info['acl'] : self::DEFAULT_ACL;
4495
  }
4496
 
4497
  if ( ! empty( $s3_info['sizes'][ $size ]['acl'] ) ) {
4498
  return $s3_info['sizes'][ $size ]['acl'];
4499
  }
4500
 
4501
- return self::DEFAULT_ACL;
4502
  }
4503
 
4504
  /**
@@ -4544,7 +4550,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
4544
  return array(
4545
  'amazon-s3-and-cloudfront-assets-pull' => array(
4546
  'title' => __( 'Assets Pull', 'amazon-s3-and-cloudfront' ),
4547
- 'sub' => __( 'An addon for WP Offload S3 to serve your site\'s JS, CSS, and other enqueued assets from Amazon CloudFront or another CDN.', 'amazon-s3-and-cloudfront'),
4548
  'url' => $this->dbrains_url( '/wp-offload-s3/doc/assets-pull-addon/', array(
4549
  'utm_campaign' => 'addons+install',
4550
  ) ),
@@ -4605,7 +4611,7 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
4605
  );
4606
  $this->notices->add_notice( $message, $args );
4607
 
4608
- if ( is_a( $this->aws, '\DeliciousBrains\WP_Offload_S3\Amazon_Web_Services' ) && $this->aws->needs_access_keys() ) {
4609
  // Have access keys been defined in still active AWS plugin's database settings?
4610
  $aws_settings = get_site_option( 'aws_settings' );
4611
 
@@ -4634,4 +4640,44 @@ class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
4634
 
4635
  $this->render_view( 'notice', $notice );
4636
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4637
  }
1
  <?php
2
 
3
+ use DeliciousBrains\WP_Offload_S3\Providers\AWS_Provider;
4
+ use DeliciousBrains\WP_Offload_S3\Providers\Null_Provider;
5
+ use DeliciousBrains\WP_Offload_S3\Providers\Provider;
6
  use DeliciousBrains\WP_Offload_S3\Upgrades\Upgrade_Content_Replace_URLs;
7
  use DeliciousBrains\WP_Offload_S3\Upgrades\Upgrade_EDD_Replace_URLs;
8
  use DeliciousBrains\WP_Offload_S3\Upgrades\Upgrade_File_Sizes;
13
  class Amazon_S3_And_CloudFront extends AS3CF_Plugin_Base {
14
 
15
  /**
16
+ * @var Provider
17
  */
18
  private $aws;
19
 
20
  /**
21
+ * @var Provider
22
  */
23
  private $s3client;
24
 
82
  */
83
  public $plugin_compat;
84
 
 
 
85
  const DEFAULT_EXPIRES = 900;
 
 
 
86
 
87
  const SETTINGS_KEY = 'tantan_wordpress_s3';
88
  const SETTINGS_CONSTANT = 'WPOS3_SETTINGS';
90
  const LATEST_UPGRADE_ROUTINE = 6;
91
 
92
  /**
93
+ * @param string $plugin_file_path
94
+ * @param string|null $slug
95
+ *
96
+ * @throws Exception
97
  */
98
+ function __construct( $plugin_file_path, $slug = null ) {
99
  $this->plugin_slug = ( is_null( $slug ) ) ? 'amazon-s3-and-cloudfront' : $slug;
100
 
101
  parent::__construct( $plugin_file_path );
102
 
 
 
 
 
 
103
  $this->notices = AS3CF_Notices::get_instance( $this );
104
 
105
  $this->init( $plugin_file_path );
114
  $this->plugin_title = __( 'Offload S3', 'amazon-s3-and-cloudfront' );
115
  $this->plugin_menu_title = __( 'Offload S3', 'amazon-s3-and-cloudfront' );
116
 
117
+ $this->set_aws( new AWS_Provider( $this ) );
118
+
119
  // Bundled SDK may require AWS setup before data migrations.
120
  $this->handle_aws_access_key_migration();
121
 
187
  }
188
 
189
  /**
190
+ * @return Provider
191
  */
192
  public function get_aws() {
193
  return $this->aws;
194
  }
195
 
196
+ /**
197
+ * TODO: Remove once Provider fully set up, this is currently required for unit tests.
198
+ *
199
+ * @param Provider $aws
200
+ */
201
+ public function set_aws( $aws ) {
202
+ $this->aws = $aws;
203
+ }
204
+
205
  /**
206
  * Get the plugin title to be used in page headings
207
  *
287
 
288
  // If legacy setting set, migrate settings
289
  if ( isset( $settings['wp-uploads'] ) &&
290
+ $settings['wp-uploads'] &&
291
+ in_array( $key, array( 'copy-to-s3', 'serve-from-s3', ) )
292
  ) {
293
  return '1';
294
  }
428
 
429
  // Region of bucket translation
430
  if ( 'region' === $key && isset( $settings['region'] ) ) {
431
+ return $this->get_aws()->sanitize_region( $settings['region'] );
 
432
  }
433
 
434
  return false;
782
  'message' => __( 'Access keys updated successfully.', 'amazon-s3-and-cloudfront' ),
783
  );
784
 
785
+ if ( AWS_Provider::is_any_access_key_constant_defined() ) {
786
  wp_send_json_error( array(
787
  'message' => __( 'All access key constants must be removed before keys can be set in the database.', 'amazon-s3-and-cloudfront' ),
788
  ) );
830
  * Remove AWS access keys from saved settings if a key constant is defined.
831
  */
832
  public function remove_aws_keys_if_constants_set() {
833
+ if ( AWS_Provider::is_any_access_key_constant_defined() ) {
834
  $this->remove_aws_keys();
835
  }
836
  }
862
 
863
  try {
864
  foreach ( $chunks as $chunk ) {
865
+ $this->get_s3client( $region, $force_new_s3_client )->delete_objects( array(
866
  'Bucket' => $bucket,
867
  'Objects' => $chunk,
868
  ) );
1026
  return $this->return_upload_error( $error_msg, $return_metadata );
1027
  }
1028
 
1029
+ $acl = $this->get_aws()->get_default_acl();
1030
 
1031
  // check the attachment already exists in S3, eg. edit or restore image
1032
  if ( ( $old_s3object = $this->get_attachment_s3_info( $post_id ) ) ) {
1090
  );
1091
 
1092
  // Do not store object ACL if set to the default value.
1093
+ if ( $s3object['acl'] === $this->get_aws()->get_default_acl() ) {
1094
  unset( $s3object['acl'] );
1095
  }
1096
 
1101
  $s3client = $this->get_s3client( $s3object['region'], $force_new_s3_client );
1102
 
1103
  try {
1104
+ $s3client->upload_object( $args );
1105
  $files_to_remove[] = $file_path;
1106
  } catch ( Exception $e ) {
1107
  $error_msg = sprintf( __( 'Error uploading %s to S3: %s', 'amazon-s3-and-cloudfront' ), $file_path, $e->getMessage() );
1115
 
1116
  $file_paths = AS3CF_Utils::get_attachment_file_paths( $post_id, false, $data );
1117
  $additional_images = array();
1118
+ $s3object_sizes = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1119
 
1120
  foreach ( $file_paths as $size => $file_path ) {
1121
  if ( ! in_array( $file_path, $files_to_remove ) ) {
1122
+ $acl = apply_filters( 'as3cf_upload_acl_sizes', $this->get_aws()->get_default_acl(), $size, $post_id, $data );
1123
 
1124
  $additional_images[ $size ] = array(
1125
  'Key' => $prefix . wp_basename( $file_path ),
1128
  'ContentType' => $this->get_mime_type( $file_path ),
1129
  );
1130
 
1131
+ if ( $this->get_aws()->get_default_acl() !== $acl ) {
1132
  $s3object_sizes[ $size ]['acl'] = $acl;
1133
  }
 
 
 
 
 
 
 
 
1134
  }
1135
  }
1136
 
1145
  }
1146
 
1147
  try {
1148
+ $s3client->upload_object( $args );
1149
  $files_to_remove[] = $image['SourceFile'];
1150
  } catch ( Exception $e ) {
1151
  $upload_errors[] = $this->return_upload_error( sprintf( __( 'Error uploading %s to S3: %s', 'amazon-s3-and-cloudfront' ), $args['SourceFile'], $e->getMessage() ) );
1152
  }
1153
  }
1154
 
1155
+ $remove_local_files_setting = $this->get_setting( 'remove-local-file' );
1156
+
1157
  if ( $remove_local_files ) {
1158
  if ( $remove_local_files_setting ) {
1159
  // Allow other functions to remove files after they have processed
1160
  $files_to_remove = apply_filters( 'as3cf_upload_attachment_local_files_to_remove', $files_to_remove, $post_id, $file_path );
1161
+
1162
  // Remove duplicates
1163
  $files_to_remove = array_unique( $files_to_remove );
 
 
 
 
1164
 
1165
+ // Delete the files and record original file's size before removal.
1166
+ $filesize = $this->remove_local_files( $files_to_remove, $post_id );
 
 
 
 
 
 
 
 
1167
 
1168
+ // Store filesize in the attachment meta data for use by WP
1169
+ if ( 0 < $filesize ) {
1170
+ $data['filesize'] = $filesize;
 
1171
 
1172
+ if ( is_null( $return_metadata ) ) {
1173
+ // Update metadata with filesize
1174
+ update_post_meta( $post_id, '_wp_attachment_metadata', $data );
1175
+ }
1176
+ }
1177
  }
1178
  }
1179
 
1180
+ // Make sure we don't have cached file sizes in the meta if we previously added it.
1181
+ if ( ! $remove_local_files_setting && isset( $data['filesize'] ) && ! empty( get_post_meta( $post_id, 'wpos3_filesize_total', true ) ) ) {
1182
+ $data = $this->maybe_cleanup_filesize_metadata( $post_id, $data, empty( $return_metadata ) );
1183
+ }
1184
+
1185
  if ( ! empty( $s3object_sizes ) ) {
1186
  // Additional image sizes have custom ACLs, update meta
1187
  $s3object['sizes'] = $s3object_sizes;
1283
  }
1284
 
1285
  /**
1286
+ * Remove files from the local site, recording total filesize in meta if attachment ID given.
1287
  *
1288
  * @param array $file_paths array of files to remove
1289
+ * @param int $attachment_id
1290
+ *
1291
+ * @return int Original file's size if attachment ID given, otherwise always 0.
1292
  */
1293
+ function remove_local_files( $file_paths, $attachment_id = 0 ) {
1294
+ $filesize = 0;
1295
+ $filesize_total = 0;
1296
+
1297
+ foreach ( $file_paths as $index => $path ) {
1298
+ if ( ! empty( $attachment_id ) && is_int( $attachment_id ) ) {
1299
+ $bytes = filesize( $path );
1300
+
1301
+ if ( false !== $bytes ) {
1302
+ $filesize_total += $bytes;
1303
+
1304
+ // Will return the original file's size.
1305
+ $filesize = $bytes;
1306
+ }
1307
+ }
1308
+
1309
+ // Individual files might still be kept local, but we're still going to count them towards total above.
1310
  if ( false !== ( $pre = apply_filters( 'as3cf_preserve_file_from_local_removal', false, $path ) ) ) {
1311
  continue;
1312
  }
1323
  AS3CF_Error::log( $message . $path );
1324
  }
1325
  }
1326
+
1327
+ // If we were able to sum up file sizes for an attachment, record it.
1328
+ if ( $filesize_total > 0 ) {
1329
+ update_post_meta( $attachment_id, 'wpos3_filesize_total', $filesize_total );
1330
+ }
1331
+
1332
+ return $filesize;
1333
  }
1334
 
1335
  /**
1361
  * @return null|string
1362
  */
1363
  function get_folder_time_from_url( $url ) {
1364
+ if ( ! is_string( $url ) ) {
1365
+ return null;
1366
+ }
1367
+
1368
  preg_match( '@[0-9]{4}/[0-9]{2}@', $url, $matches );
1369
 
1370
  if ( isset( $matches[0] ) ) {
1558
  $prefix = AS3CF_Utils::trailingslash_prefix( $this->get_object_prefix() );
1559
  $prefix .= AS3CF_Utils::trailingslash_prefix( $this->get_dynamic_prefix( $time ) );
1560
 
1561
+ return $s3client->does_object_exist( $bucket, $prefix . $filename );
1562
  }
1563
 
1564
  /**
1609
  * @return bool
1610
  */
1611
  function is_plugin_setup( $with_credentials = false ) {
1612
+ if ( $with_credentials && $this->get_aws()->needs_access_keys() ) {
1613
  // AWS not configured
1614
  return false;
1615
  }
1743
  $prefix .= $delimiter . $region;
1744
  }
1745
 
1746
+ return apply_filters( 'as3cf_s3_url_prefix', $prefix, $region );
1747
  }
1748
 
1749
  /**
1755
  * @param array $args Allows you to specify custom URL settings
1756
  * @param bool $preview When generating the URL preview sanitize certain output
1757
  *
1758
+ * @return string
1759
  */
1760
  function get_s3_url_domain( $bucket, $region = '', $expires = null, $args = array(), $preview = false ) {
1761
  if ( ! isset( $args['cloudfront'] ) ) {
1770
  $args['force-https'] = $this->get_setting( 'force-https' );
1771
  }
1772
 
1773
+ $prefix = $this->get_s3_url_prefix( $region, $expires );
1774
+ $s3_domain = apply_filters( 'as3cf_s3_domain', 'amazonaws.com' );
1775
+ $s3_domain = empty( $prefix ) ? $s3_domain : $prefix . '.' . $s3_domain;
1776
+
1777
 
1778
  if ( 'cloudfront' === $args['domain'] && is_null( $expires ) && $args['cloudfront'] ) {
1779
  $cloudfront = $args['cloudfront'];
1785
  } elseif ( 'virtual-host' === $args['domain'] ) {
1786
  $s3_domain = $bucket;
1787
  } elseif ( 'path' === $args['domain'] || $this->use_ssl( $args['force-https'] ) ) {
1788
+ $s3_domain = $s3_domain . '/' . $bucket;
1789
  } else {
1790
+ $s3_domain = $bucket . '.' . $s3_domain;
1791
  }
1792
 
1793
  return $s3_domain;
1899
 
1900
  // We don't use $this->get_s3object_region() here because we don't want
1901
  // to make an AWS API call and slow down page loading
1902
+ if ( isset( $s3object['region'] ) && $this->get_aws()->get_default_region() !== $s3object['region'] ) {
1903
+ $region = $this->get_aws()->sanitize_region( $s3object['region'] );
1904
  } else {
1905
  $region = '';
1906
  }
1909
 
1910
  // Force use of secured URL when ACL has been set to private
1911
  if ( is_null( $expires ) ) {
1912
+ if ( is_null( $size ) && isset( $s3object['acl'] ) && $this->get_aws()->get_private_acl() === $s3object['acl'] ) {
1913
  // Full size URL private
1914
  $expires = self::DEFAULT_EXPIRES;
1915
  }
1916
 
1917
+ if ( ! is_null( $size ) && isset( $s3object['sizes'][ $size ]['acl'] ) && $this->get_aws()->get_private_acl() === $s3object['sizes'][ $size ]['acl'] ) {
1918
  // Alternative size URL private
1919
  $expires = self::DEFAULT_EXPIRES;
1920
  }
1941
  try {
1942
  $expires = time() + apply_filters( 'as3cf_expires', $expires );
1943
  $secure_url = $this->get_s3client( $region )
1944
+ ->get_object_url( $s3object['bucket'], $s3object['key'], $expires, $headers );
1945
 
1946
  return apply_filters( 'as3cf_get_attachment_secure_url', $secure_url, $s3object, $post_id, $expires, $headers );
1947
  } catch ( Exception $e ) {
1997
  return $html;
1998
  }
1999
 
2000
+ if ( ! is_string( $html ) ) {
2001
+ return $html;
2002
+ }
2003
+
2004
  preg_match( '@\ssrc=[\'\"]([^\'\"]*)[\'\"]@', $html, $matches );
2005
 
2006
  if ( ! isset( $matches[1] ) ) {
2327
  wp_send_json( $return );
2328
  }
2329
 
2330
+ /**
2331
+ * Ensure AJAX request from expected route and user with capability to handle offloaded media.
2332
+ *
2333
+ * @param string $capability Defaults to 'manage_options'.
2334
+ * @param bool $return
2335
+ *
2336
+ * @return bool
2337
+ */
2338
+ function verify_ajax_request( $capability = null, $return = false ) {
2339
+ $capability = empty( $capability ) ? 'manage_options' : $capability;
2340
+
2341
+ if ( ! is_admin() ) { // input var okay
2342
+ $msg = __( 'This action can only be performed through an admin screen.', 'amazon-s3-and-cloudfront' );
2343
+ } elseif ( empty( $_POST['_nonce'] ) || empty( $_POST['action'] ) || ! wp_verify_nonce( sanitize_key( $_POST['_nonce'] ), sanitize_key( $_POST['action'] ) ) ) { // input var okay
2344
+ $msg = __( 'Cheatin&#8217; eh?', 'amazon-s3-and-cloudfront' );
2345
+ } elseif ( ! current_user_can( $capability ) ) {
2346
+ $msg = __( 'You do not have sufficient permissions to access this page.', 'amazon-s3-and-cloudfront' );
2347
  }
2348
 
2349
+ if ( ! empty( $msg ) ) {
2350
+ AS3CF_Error::log( $msg );
2351
+
2352
+ if ( $return ) {
2353
+ return false;
2354
+ } else {
2355
+ wp_die( $msg );
2356
+ }
2357
  }
2358
+
2359
+ return true;
2360
  }
2361
 
2362
  function ajax_check_bucket() {
2419
  $region = AS3CF_REGION;
2420
  }
2421
 
2422
+ if ( ! is_null( $region ) && $this->get_aws()->get_default_region() !== $region ) {
2423
  $args['LocationConstraint'] = $region;
2424
  }
2425
 
2426
+ $this->get_s3client()->create_bucket( $args );
2427
  } catch ( Exception $e ) {
2428
  return new WP_Error( 'exception', $e->getMessage() );
2429
  }
2537
  }
2538
  }
2539
 
2540
+ if ( $this->get_aws()->get_default_region() === $region ) {
2541
  $region = '';
2542
  }
2543
 
2591
  );
2592
  }
2593
 
2594
+ /**
2595
+ * Returns the Provider's default region slug.
2596
+ *
2597
+ * @return string
2598
+ */
2599
+ public function get_default_region() {
2600
+ return $this->get_aws()->get_default_region();
2601
+ }
2602
+
2603
  /**
2604
  * Get the S3 client
2605
  *
2606
  * @param bool|string $region specify region to client for signature
2607
  * @param bool $force force return of new S3 client when swapping regions
2608
  *
2609
+ * @return Provider|Null_Provider
2610
  */
2611
  public function get_s3client( $region = false, $force = false ) {
2612
  if ( is_null( $this->s3client ) ||
2613
  is_null( $this->s3client_region ) ||
2614
  $force ||
2615
  ( false !== $region && $this->s3client_region !== $region ) ) {
2616
+ $args = array();
2617
 
2618
+ if ( $force ) {
2619
+ $this->set_aws( new AWS_Provider( $this ) );
2620
+ }
2621
 
2622
  if ( $region ) {
2623
+ $args['region'] = $this->get_aws()->sanitize_region( $region );
 
2624
  }
2625
 
2626
  $s3client_region = isset( $args['region'] ) ? $args['region'] : $region;
2627
 
2628
  try {
2629
+ $this->set_client( $this->get_aws()->get_client( $args ), $s3client_region );
 
2630
  } catch ( \Exception $e ) {
2631
  AS3CF_Error::log( $e->getMessage() );
2632
+ $this->set_client( new Null_Provider );
2633
  }
2634
  }
2635
 
2639
  /**
2640
  * Setter for S3 client
2641
  *
2642
+ * @param Provider|Null_Provider $client
2643
+ * @param bool|string $region
2644
  */
2645
  public function set_client( $client, $region = false ) {
2646
  $this->s3client = $client;
2670
  }
2671
 
2672
  try {
2673
+ $region = $this->get_s3client()->get_bucket_location( array( 'Bucket' => $bucket ) );
2674
  } catch ( Exception $e ) {
2675
  $error_msg_title = '<strong>' . __( 'Error Getting Bucket Region', 'amazon-s3-and-cloudfront' ) . '</strong> &mdash;';
2676
  $error_msg = sprintf( __( 'There was an error attempting to get the region of the bucket %s: %s', 'amazon-s3-and-cloudfront' ), $bucket, $e->getMessage() );
2679
  return new WP_Error( 'exception', $error_msg_title . $error_msg );
2680
  }
2681
 
2682
+ $region = $this->get_aws()->sanitize_region( $region );
2683
 
2684
  if ( is_string( $region ) ) {
2685
  $regions[ $bucket ] = $region;
2717
  return $s3object['region'];
2718
  }
2719
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2720
  /**
2721
  * AJAX handler for get_buckets()
2722
  */
2743
  */
2744
  function get_buckets() {
2745
  try {
2746
+ $result = $this->get_s3client()->list_buckets();
2747
  } catch ( Exception $e ) {
2748
  return new WP_Error( 'exception', $e->getMessage() );
2749
  }
2760
  * @return bool|WP_Error
2761
  */
2762
  function check_write_permission( $bucket = null, $region = null ) {
2763
+ if ( $this->get_aws()->needs_access_keys() ) {
2764
  // If no access keys set then no need check.
2765
  return false;
2766
  }
2785
  return self::$buckets_check[ $bucket ];
2786
  }
2787
 
2788
+ $key = $this->get_file_prefix() . 'as3cf-permission-check.txt';
2789
  $file_contents = __( 'This is a test file to check if the user has write permission to S3. Delete me if found.', 'amazon-s3-and-cloudfront' );
2790
 
2791
+ $can_write = $this->get_s3client( $region, true )->can_write( $bucket, $key, $file_contents );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2792
 
2793
+ // If we get back an unexpected error message, throw an error.
2794
+ if ( is_string( $can_write ) ) {
2795
+ $error_msg = sprintf( __( 'There was an error attempting to check the permissions of the bucket %s: %s', 'amazon-s3-and-cloudfront' ), $bucket, $can_write );
2796
+ AS3CF_Error::log( $error_msg );
2797
 
2798
+ return new WP_Error( 'exception', $error_msg );
 
2799
  }
2800
 
2801
  self::$buckets_check[ $bucket ] = $can_write;
2853
  wp_localize_script( 'as3cf-script',
2854
  'as3cf',
2855
  array(
2856
+ 'strings' => array(
2857
  'create_bucket_error' => __( 'Error creating bucket', 'amazon-s3-and-cloudfront' ),
2858
  'create_bucket_name_short' => __( 'Bucket name too short.', 'amazon-s3-and-cloudfront' ),
2859
  'create_bucket_name_long' => __( 'Bucket name too long.', 'amazon-s3-and-cloudfront' ),
2868
  // Mimic WP Core's notice text, therefore no translation needed here.
2869
  'settings_saved' => __( 'Settings saved.' ),
2870
  ),
2871
+ 'nonces' => array(
2872
  'create_bucket' => wp_create_nonce( 'as3cf-create-bucket' ),
2873
  'manual_bucket' => wp_create_nonce( 'as3cf-manual-save-bucket' ),
2874
  'get_buckets' => wp_create_nonce( 'as3cf-get-buckets' ),
2878
  'aws_keys_set' => wp_create_nonce( 'as3cf-aws-keys-set' ),
2879
  'aws_keys_remove' => wp_create_nonce( 'as3cf-aws-keys-remove' ),
2880
  ),
2881
+ 'is_pro' => $this->is_pro(),
2882
+ 'aws_bucket_link' => $this->get_aws_bucket_link(),
2883
+ 'aws_bucket_link_param' => $this->get_aws_bucket_link_param(),
2884
  )
2885
  );
2886
 
2942
 
2943
  do_action( 'as3cf_pre_save_settings' );
2944
 
2945
+ $post_vars = $this->get_settings_whitelist();
2946
 
2947
  foreach ( $post_vars as $var ) {
2948
  $this->remove_setting( $var );
3007
 
3008
  foreach ( $addons as $slug => $addon ) {
3009
  $this->render_view( 'addon', array(
3010
+ 'slug' => $slug,
3011
+ 'addon' => $addon,
3012
  ) );
3013
  }
3014
  }
3165
  */
3166
  function get_aws_bucket_link( $bucket = '', $prefix = '' ) {
3167
  if ( '' !== $prefix ) {
3168
+ $prefix = $this->get_aws_bucket_link_param() . urlencode( apply_filters( 'as3cf_s3_console_url_prefix_value', $prefix ) );
3169
  }
3170
 
3171
+ return apply_filters( 'as3cf_s3_console_url', 'https://console.aws.amazon.com/s3/home?bucket=' ) . $bucket . $prefix;
3172
+ }
3173
+
3174
+ /**
3175
+ * Get the link to the bucket on the AWS console's prefix param.
3176
+ *
3177
+ * @return string
3178
+ */
3179
+ function get_aws_bucket_link_param() {
3180
+ return apply_filters( 'as3cf_s3_console_url_prefix_param', '&prefix=' );
3181
  }
3182
 
3183
  /**
3205
  $s3client = $this->get_s3client( $region, true );
3206
 
3207
  try {
3208
+ $s3client->update_object_acl( $args );
3209
  $s3object['acl'] = $acl;
3210
 
3211
  // update S3 meta data
3212
+ if ( $acl == $this->get_aws()->get_default_acl() ) {
3213
  unset( $s3object['acl'] );
3214
  }
3215
 
3231
  */
3232
  function make_acl_admin_notice( $s3object ) {
3233
  $filename = wp_basename( $s3object['key'] );
3234
+ $acl = ( isset( $s3object['acl'] ) ) ? $s3object['acl'] : $this->get_aws()->get_default_acl();
3235
  $acl_name = $this->get_acl_display_name( $acl );
3236
  $text = sprintf( __( '<strong>WP Offload S3</strong> &mdash; The file %s has been given %s permissions on Amazon S3.', 'amazon-s3-and-cloudfront' ), "<strong>{$filename}</strong>", "<strong>{$acl_name}</strong>" );
3237
 
3425
  }
3426
  $output .= "\r\n";
3427
 
3428
+ $output .= 'allow_url_fopen: ';
3429
  $allow_url_fopen = ini_get( 'allow_url_fopen' );
3430
  if ( empty( $allow_url_fopen ) ) {
3431
  $output .= 'Disabled';
3444
 
3445
  $output .= 'cURL: ';
3446
  if ( function_exists( 'curl_init' ) ) {
3447
+ $curl = curl_version();
3448
  $output .= esc_html( $curl['version'] );
3449
  } else {
3450
  $output .= 'Disabled';
3462
  $output .= 'PHP GD: ';
3463
  if ( $this->gd_enabled() ) {
3464
  $gd_info = gd_info();
3465
+ $output .= isset( $gd_info['GD Version'] ) ? esc_html( $gd_info['GD Version'] ) : 'Enabled';
3466
  } else {
3467
  $output .= 'Disabled';
3468
  }
3503
  $output .= "\r\n";
3504
 
3505
  $output .= 'Number of Image Sizes: ';
3506
+ $sizes = count( get_intermediate_image_sizes() );
3507
  $output .= number_format_i18n( $sizes );
3508
  $output .= "\r\n\r\n";
3509
 
3510
+ $output .= 'Names and Dimensions of Image Sizes: ';
3511
+ $output .= "\r\n";
3512
  $size_details = $this->get_image_sizes_details();
3513
+ $output .= $size_details;
3514
+ $output .= "\r\n";
3515
 
3516
  $output .= 'WP_CONTENT_DIR: ';
3517
  $output .= esc_html( ( defined( 'WP_CONTENT_DIR' ) ) ? WP_CONTENT_DIR : 'Not defined' );
3598
  }
3599
 
3600
  $theme_info = wp_get_theme();
3601
+ $output .= "Active Theme Name: " . esc_html( $theme_info->get( 'Name' ) );
3602
+ $output .= "\r\n";
3603
+ $output .= "Active Theme Version: " . esc_html( $theme_info->get( 'Version' ) );
3604
+ $output .= "\r\n";
3605
+ $output .= "Active Theme Folder: " . esc_html( $theme_info->get_stylesheet() );
3606
+ $output .= "\r\n";
3607
 
3608
  if ( is_child_theme() ) {
3609
  $parent_info = $theme_info->parent();
3610
+ $output .= "Parent Theme Name: " . esc_html( $parent_info->get( 'Name' ) );
3611
+ $output .= "\r\n";
3612
+ $output .= "Parent Theme Version: " . esc_html( $parent_info->get( 'Version' ) );
3613
+ $output .= "\r\n";
3614
+ $output .= "Parent Theme Folder: " . esc_html( $parent_info->get_stylesheet() );
3615
+ $output .= "\r\n";
3616
  }
3617
  if ( ! file_exists( $theme_info->get_stylesheet_directory() ) ) {
3618
  $output .= "WARNING: Active Theme Folder Not Found\r\n";
3620
 
3621
  $output .= "\r\n";
3622
 
3623
+ $output .= "Active Plugins:\r\n";
3624
  $active_plugins = (array) get_option( 'active_plugins', array() );
3625
  $plugin_details = array();
3626
 
3639
  $mu_plugins = wp_get_mu_plugins();
3640
  if ( $mu_plugins ) {
3641
  $mu_plugin_details = array();
3642
+ $output .= "\r\n";
3643
+ $output .= "Must-use Plugins:\r\n";
3644
 
3645
  foreach ( $mu_plugins as $mu_plugin ) {
3646
  $mu_plugin_details[] = $this->get_plugin_details( $mu_plugin );
3865
  * @return string
3866
  */
3867
  function get_access_denied_notice_message( $single = true ) {
3868
+ if ( $this->get_aws()->needs_access_keys() ) {
3869
  return sprintf( __( '<a href="%s">Define your AWS keys</a> to enable write access to the bucket', 'amazon-s3-and-cloudfront' ), '#settings' );
3870
  }
3871
 
3984
  AND pm.`meta_key` = 'amazonS3_info'";
3985
 
3986
  $operator = $uploaded_to_s3 ? 'not ' : '';
3987
+ $where .= " AND pm.`post_id` is {$operator}null";
3988
  }
3989
 
3990
  $sql .= ' ' . $where;
4004
  $all_media_s3 = 0;
4005
 
4006
  foreach ( $table_prefixes as $blog_id => $table_prefix ) {
4007
+ $count = $this->count_attachments( $table_prefix );
4008
+ $all_media += $count;
4009
+ $s3_count = $this->count_attachments( $table_prefix, true );
4010
  $all_media_s3 += $s3_count;
4011
  }
4012
 
4176
  );
4177
 
4178
  $doc_url = $this->dbrains_url( '/wp-offload-s3/doc/force-http-setting/', array(
4179
+ 'utm_campaign' => 'support+docs',
4180
  ) );
4181
  $doc_link = AS3CF_Utils::dbrains_link( $doc_url, __( 'this doc' ) );
4182
 
4247
  $file = get_attached_file( $post->ID, true );
4248
 
4249
  $args = array(
4250
+ 's3object' => $this->get_formatted_s3_info( $post->ID ),
4251
+ 'post' => $post,
4252
+ 'local_file_exists' => file_exists( $file ),
4253
+ 'available_actions' => $this->get_available_media_actions( 'singular' ),
4254
+ 'sendback' => 'post.php?post=' . $post->ID . '&action=edit',
4255
  );
4256
 
4257
  $this->render_view( 'attachment-metabox', $args );
4285
 
4286
  $s3object['url'] = $this->get_attachment_s3_url( $id, $s3object );
4287
 
4288
+ $acl = ( isset( $s3object['acl'] ) ) ? $s3object['acl'] : $this->get_aws()->get_default_acl();
4289
  $acl_info = array(
4290
  'acl' => $acl,
4291
  'name' => $this->get_acl_display_name( $acl ),
4292
  'title' => $this->get_media_action_strings( 'change_to_private' ),
4293
  );
4294
 
4295
+ if ( $this->get_aws()->get_private_acl() === $acl ) {
4296
  $acl_info['title'] = $this->get_media_action_strings( 'change_to_public' );
4297
  }
4298
 
4299
  $s3object['acl'] = $acl_info;
4300
 
4301
+ $regions = $this->get_aws()->get_regions();
4302
 
4303
  if ( isset( $s3object['region'] ) && '' == $s3object['region'] ) {
4304
+ $s3object['region'] = $this->get_aws()->get_default_region();
4305
  }
4306
 
4307
  if ( isset( $regions[ $s3object['region'] ] ) ) {
4348
  ) );
4349
 
4350
  wp_localize_script( 'as3cf-media-script', 'as3cf_media', array(
4351
+ 'strings' => $this->get_media_action_strings(),
4352
+ 'nonces' => array(
4353
+ 'get_attachment_s3_details' => wp_create_nonce( 'get-attachment-s3-details' ),
4354
+ ),
4355
+ ) );
4356
  }
4357
 
4358
  /**
4497
  $s3_info = $this->get_attachment_s3_info( $attachment_id );
4498
 
4499
  if ( 'original' === $size || empty( $size ) ) {
4500
+ return isset( $s3_info['acl'] ) ? $s3_info['acl'] : $this->get_aws()->get_default_acl();
4501
  }
4502
 
4503
  if ( ! empty( $s3_info['sizes'][ $size ]['acl'] ) ) {
4504
  return $s3_info['sizes'][ $size ]['acl'];
4505
  }
4506
 
4507
+ return $this->get_aws()->get_default_acl();
4508
  }
4509
 
4510
  /**
4550
  return array(
4551
  'amazon-s3-and-cloudfront-assets-pull' => array(
4552
  'title' => __( 'Assets Pull', 'amazon-s3-and-cloudfront' ),
4553
+ 'sub' => __( 'An addon for WP Offload S3 to serve your site\'s JS, CSS, and other enqueued assets from Amazon CloudFront or another CDN.', 'amazon-s3-and-cloudfront' ),
4554
  'url' => $this->dbrains_url( '/wp-offload-s3/doc/assets-pull-addon/', array(
4555
  'utm_campaign' => 'addons+install',
4556
  ) ),
4611
  );
4612
  $this->notices->add_notice( $message, $args );
4613
 
4614
+ if ( is_a( $this->get_aws(), '\DeliciousBrains\WP_Offload_S3\Providers\AWS_Provider' ) && $this->get_aws()->needs_access_keys() ) {
4615
  // Have access keys been defined in still active AWS plugin's database settings?
4616
  $aws_settings = get_site_option( 'aws_settings' );
4617
 
4640
 
4641
  $this->render_view( 'notice', $notice );
4642
  }
4643
+
4644
+ /**
4645
+ * Remove 'filesize' from attachment's metatdata if appropriate, also our total filesize record.
4646
+ *
4647
+ * @param integer $post_id Attachment's post_id.
4648
+ * @param array $data Attachment's metadata.
4649
+ * @param bool $update_metadata Update the metadata record now? Defaults to true.
4650
+ *
4651
+ * @return array Attachment's cleaned up metadata.
4652
+ */
4653
+ public function maybe_cleanup_filesize_metadata( $post_id, $data, $update_metadata = true ) {
4654
+ if ( ! is_int( $post_id ) || empty( $post_id ) || empty( $data ) ) {
4655
+ return $data;
4656
+ }
4657
+
4658
+ /*
4659
+ * Audio and video have a filesize added to metadata by default, but images and anything else don't.
4660
+ * Note: Could have used `wp_generate_attachment_metadata` here to test whether default metadata has 'filesize',
4661
+ * but it not only has side effects it also does a lot of work considering it's not a huge deal for this entry to hang around.
4662
+ */
4663
+ if (
4664
+ empty( $data['mime_type'] ) ||
4665
+ 0 === strpos( $data['mime_type'], 'image/' ) ||
4666
+ ! ( 0 === strpos( $data['mime_type'], 'audio/' ) || 0 === strpos( $data['mime_type'], 'video/' ) )
4667
+ ) {
4668
+ unset( $data['filesize'] );
4669
+ }
4670
+
4671
+ if ( $update_metadata ) {
4672
+ if ( empty( $data ) ) {
4673
+ delete_post_meta( $post_id, '_wp_attachment_metadata' );
4674
+ } else {
4675
+ update_post_meta( $post_id, '_wp_attachment_metadata', $data );
4676
+ }
4677
+ }
4678
+
4679
+ delete_post_meta( $post_id, 'wpos3_filesize_total' );
4680
+
4681
+ return $data;
4682
+ }
4683
  }
classes/amazon-web-services.php DELETED
@@ -1,167 +0,0 @@
1
- <?php
2
-
3
- namespace DeliciousBrains\WP_Offload_S3;
4
-
5
- use AS3CF_Utils;
6
- use DeliciousBrains\WP_Offload_S3\Aws2\Aws\Common\Aws;
7
- use Exception;
8
-
9
- class Amazon_Web_Services extends \AS3CF_Plugin_Base {
10
-
11
- /**
12
- * @var
13
- */
14
- private $client;
15
-
16
- protected $plugin_slug = 'amazon-s3-and-cloudfront';
17
-
18
- const SETTINGS_KEY = \Amazon_S3_And_CloudFront::SETTINGS_KEY;
19
-
20
- /**
21
- * Whether or not IAM access keys are needed.
22
- *
23
- * Keys are needed if we are not using EC2 roles or not defined/set yet.
24
- *
25
- * @return bool
26
- */
27
- public function needs_access_keys() {
28
- if ( $this->use_ec2_iam_roles() ) {
29
- return false;
30
- }
31
-
32
- return ! $this->are_access_keys_set();
33
- }
34
-
35
- /**
36
- * Check if both access key id & secret are present.
37
- *
38
- * @return bool
39
- */
40
- function are_access_keys_set() {
41
- return $this->get_access_key_id() && $this->get_secret_access_key();
42
- }
43
-
44
- /**
45
- * Get the AWS key from a constant or the settings.
46
- *
47
- * Falls back to settings only if neither constant is defined.
48
- *
49
- * @return string
50
- */
51
- public function get_access_key_id() {
52
- if ( $this->is_any_access_key_constant_defined() ) {
53
- $constant = $this->access_key_id_constant();
54
-
55
- return $constant ? constant( $constant ) : '';
56
- }
57
-
58
- return $this->get_setting( 'aws-access-key-id' );
59
- }
60
-
61
- /**
62
- * Get the AWS secret from a constant or the settings
63
- *
64
- * Falls back to settings only if neither constant is defined.
65
- *
66
- * @return string
67
- */
68
- public function get_secret_access_key() {
69
- if ( $this->is_any_access_key_constant_defined() ) {
70
- $constant = $this->secret_access_key_constant();
71
-
72
- return $constant ? constant( $constant ) : '';
73
- }
74
-
75
- return $this->get_setting( 'aws-secret-access-key' );
76
- }
77
-
78
- /**
79
- * Check if any access key (id or secret, prefixed or not) is defined.
80
- *
81
- * @return bool
82
- */
83
- public static function is_any_access_key_constant_defined() {
84
- return static::access_key_id_constant() || static::secret_access_key_constant();
85
- }
86
-
87
- /**
88
- * Allows the AWS client factory to use the IAM role for EC2 instances
89
- * instead of key/secret for credentials
90
- * http://docs.aws.amazon.com/aws-sdk-php/guide/latest/credentials.html#instance-profile-credentials
91
- *
92
- * @return bool
93
- */
94
- public function use_ec2_iam_roles() {
95
- $constant = $this->use_ec2_iam_role_constant();
96
-
97
- return $constant && constant( $constant );
98
- }
99
-
100
- /**
101
- * Get the constant used to define the aws access key id.
102
- *
103
- * @return string|false Constant name if defined, otherwise false
104
- */
105
- public static function access_key_id_constant() {
106
- return AS3CF_Utils::get_first_defined_constant( array(
107
- 'AS3CF_AWS_ACCESS_KEY_ID',
108
- 'DBI_AWS_ACCESS_KEY_ID',
109
- 'AWS_ACCESS_KEY_ID',
110
- ) );
111
- }
112
-
113
- /**
114
- * Get the constant used to define the aws secret access key.
115
- *
116
- * @return string|false Constant name if defined, otherwise false
117
- */
118
- public static function secret_access_key_constant() {
119
- return AS3CF_Utils::get_first_defined_constant( array(
120
- 'AS3CF_AWS_SECRET_ACCESS_KEY',
121
- 'DBI_AWS_SECRET_ACCESS_KEY',
122
- 'AWS_SECRET_ACCESS_KEY',
123
- ) );
124
- }
125
-
126
- /**
127
- * Get the constant used to enable the use of EC2 IAM roles.
128
- *
129
- * @return string|false Constant name if defined, otherwise false
130
- */
131
- public static function use_ec2_iam_role_constant() {
132
- return AS3CF_Utils::get_first_defined_constant( array(
133
- 'AS3CF_AWS_USE_EC2_IAM_ROLE',
134
- 'DBI_AWS_USE_EC2_IAM_ROLE',
135
- 'AWS_USE_EC2_IAM_ROLE',
136
- ) );
137
- }
138
-
139
- /**
140
- * Instantiate a new AWS service client for the AWS SDK
141
- * using the defined AWS key and secret
142
- *
143
- * @return Aws
144
- * @throws Exception
145
- */
146
- function get_client() {
147
- if ( $this->needs_access_keys() ) {
148
- throw new Exception( sprintf( __( 'You must first <a href="%s">set your AWS access keys</a> to use this addon.', 'amazon-s3-and-cloudfront' ), $this->get_plugin_page_url() . '#settings' ) );
149
- }
150
-
151
- if ( is_null( $this->client ) ) {
152
- $args = array();
153
-
154
- if ( ! $this->use_ec2_iam_roles() ) {
155
- $args = array(
156
- 'key' => $this->get_access_key_id(),
157
- 'secret' => $this->get_secret_access_key(),
158
- );
159
- }
160
-
161
- $args = apply_filters( 'aws_get_client_args', $args );
162
- $this->client = Aws::factory( $args );
163
- }
164
-
165
- return $this->client;
166
- }
167
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/as3cf-compatibility-check.php CHANGED
@@ -615,8 +615,8 @@ if ( ! class_exists( 'AS3CF_Compatibility_Check' ) ) {
615
 
616
  $errors = array();
617