W3 Total Cache - Version 0.9.5.2

Version Description

  • Fixed security issue by protecting configuration data by adding .php to relevant files
  • Fixed security issue with the creation of dot folders that could be abused
  • Fixed handling HTTP compression for uncached pages
  • Fixed handling of .svgz files
  • Added expiration headers to webP images
  • Added support for Microsoft Azures latest API
  • Added ability to cache WP Admin. Recommended setting, is off. (Improved WP Admin performance with object caching enabled)
  • Added HTTP/2 Push support for minified files
  • Added option management support for wp-cli
  • Improved handling of uncompressed minified files
  • Improved handling of purging of modified pages / posts
  • Improved compatibility with Rackspace Cloud Files
  • Improved initial CDN configuration reliability
  • Improved reliability of object caching
  • Improved PHP 7.0 compatibility
  • Improved PHP 4.3 compatibility
  • Improved HTTP/2 support
  • Improved CSS embed handling
  • Improved reliability of object cache, transients now fallback to database
  • Improved handling of cached http compressed objects
Download this release

Release Info

Developer fredericktownes
Plugin Icon 128x128 W3 Total Cache
Version 0.9.5.2
Comparing to
See all releases

Code changes from version 0.9.5.1 to 0.9.5.2

Files changed (232) hide show
  1. BrowserCache_Environment.php +4 -3
  2. BrowserCache_Plugin.php +3 -2
  3. Cache.php +3 -3
  4. Cache_File_Generic.php +11 -11
  5. Cache_Memcache.php +6 -0
  6. Cache_Memcached.php +6 -0
  7. CdnEngine_Azure.php +57 -114
  8. CdnEngine_GoogleDrive.php +9 -1
  9. Cdn_Core.php +1 -1
  10. Cdn_Plugin.php +39 -15
  11. Cdn_RackSpace_Api_CaCert.pem → Cdn_RackSpace_Api_CaCert-example.pem +0 -0
  12. Cdn_RackSpace_Api_Cdn.php +24 -8
  13. Cdn_RackSpace_Api_CloudFiles.php +14 -7
  14. Cdn_RackSpace_Api_CloudFilesCdn.php +12 -5
  15. Cdn_RackSpace_Api_Tokens.php +2 -2
  16. Cdn_Util.php +19 -0
  17. Cli.php +218 -86
  18. Config.php +24 -3
  19. ConfigCompiler.php +43 -8
  20. ConfigKeys.php +24 -3
  21. DbCache_Core.php +4 -4
  22. DbCache_Plugin_Admin.php +4 -4
  23. DbCache_WpdbInjection_QueryCaching.php +6 -5
  24. Dispatcher.php +3 -4
  25. Enterprise_Dbcache_WpdbInjection_Cluster.php +33 -30
  26. Enterprise_SnsServer.php +6 -0
  27. Extension_CloudFlare_Plugin.php +7 -1
  28. Extension_CloudFlare_Plugin_Admin.php +2 -1
  29. Extension_FragmentCache_Plugin_Admin.php +4 -4
  30. Extension_FragmentCache_WpObjectCache.php +4 -4
  31. Extension_Genesis_Plugin.php +1 -0
  32. Extension_NewRelic_Plugin.php +1 -1
  33. Extensions_Plugin_Admin.php +1 -1
  34. Generic_AdminActions_Flush.php +4 -4
  35. Generic_AdminActions_Test.php +13 -13
  36. Generic_ConfigLabels.php +1 -1
  37. Generic_Environment.php +14 -6
  38. Generic_Page_Dashboard.php +1 -1
  39. Generic_Page_General.php +1 -1
  40. Generic_Plugin.php +4 -9
  41. Generic_Plugin_Admin.php +26 -26
  42. Generic_Plugin_AdminNotifications.php +1 -1
  43. Minify_ConfigLabels.php +1 -1
  44. Minify_ContentMinifier.php +9 -9
  45. Minify_Core.php +16 -5
  46. Minify_Environment.php +29 -21
  47. Minify_MinifiedFileRequestHandler.php +34 -42
  48. Minify_Plugin.php +300 -224
  49. Minify_Plugin_Admin.php +5 -5
  50. ObjectCache_Plugin.php +2 -2
  51. ObjectCache_Plugin_Admin.php +4 -4
  52. ObjectCache_WpObjectCache_Regular.php +235 -43
  53. PgCache_ContentGrabber.php +161 -111
  54. PgCache_Plugin.php +1 -1
  55. PgCache_Plugin_Admin.php +14 -13
  56. UsageStatistics_Widget.php +15 -7
  57. UsageStatistics_Widget_View.php +107 -103
  58. Util_Content.php +23 -5
  59. Util_Debug.php +1 -1
  60. Util_Environment.php +49 -40
  61. Util_File.php +47 -4
  62. Util_PageUrls.php +1 -1
  63. Util_Rule.php +0 -17
  64. Util_RuleSnippet.php +1 -1
  65. Util_Ui.php +1 -1
  66. Util_WpFile.php +1 -1
  67. inc/lightbox/self_test.php +0 -9
  68. inc/mime/html.php +1 -1
  69. inc/mime/other.php +1 -0
  70. inc/options/cdn.php +1 -1
  71. inc/options/minify.php +32 -3
  72. inc/options/objectcache.php +13 -0
  73. inc/options/parts/memcached.php +4 -4
  74. inc/options/parts/memcached_extension.php +3 -3
  75. inc/options/parts/redis.php +1 -1
  76. inc/options/pgcache.php +2 -2
  77. languages/faq-pro-en_US.xml +204 -204
  78. languages/w3-total-cache-ar_AR.po +1 -1
  79. languages/w3-total-cache-nl_NL.po +1 -1
  80. languages/w3-total-cache-pl_PL.po +1 -1
  81. languages/w3-total-cache-sr_RS.po +1 -1
  82. lib/Azure/GuzzleHttp/Client.php +408 -0
  83. lib/Azure/GuzzleHttp/ClientInterface.php +84 -0
  84. lib/Azure/GuzzleHttp/Cookie/CookieJar.php +265 -0
  85. lib/Azure/GuzzleHttp/Cookie/CookieJarInterface.php +84 -0
  86. lib/Azure/GuzzleHttp/Cookie/FileCookieJar.php +90 -0
  87. lib/Azure/GuzzleHttp/Cookie/SessionCookieJar.php +71 -0
  88. lib/Azure/GuzzleHttp/Cookie/SetCookie.php +404 -0
  89. lib/Azure/GuzzleHttp/Exception/BadResponseException.php +7 -0
  90. lib/Azure/GuzzleHttp/Exception/ClientException.php +7 -0
  91. lib/Azure/GuzzleHttp/Exception/ConnectException.php +37 -0
  92. lib/Azure/GuzzleHttp/Exception/GuzzleException.php +4 -0
  93. lib/Azure/GuzzleHttp/Exception/RequestException.php +210 -0
  94. lib/Azure/GuzzleHttp/Exception/SeekException.php +27 -0
  95. lib/Azure/GuzzleHttp/Exception/ServerException.php +7 -0
  96. lib/Azure/GuzzleHttp/Exception/TooManyRedirectsException.php +4 -0
  97. lib/Azure/GuzzleHttp/Exception/TransferException.php +4 -0
  98. lib/Azure/GuzzleHttp/Handler/CurlFactory.php +536 -0
  99. lib/Azure/GuzzleHttp/Handler/CurlFactoryInterface.php +27 -0
  100. lib/Azure/GuzzleHttp/Handler/CurlHandler.php +45 -0
  101. lib/Azure/GuzzleHttp/Handler/CurlMultiHandler.php +197 -0
  102. lib/Azure/GuzzleHttp/Handler/EasyHandle.php +92 -0
  103. lib/Azure/GuzzleHttp/Handler/MockHandler.php +176 -0
  104. lib/Azure/GuzzleHttp/Handler/Proxy.php +55 -0
  105. lib/Azure/GuzzleHttp/Handler/StreamHandler.php +490 -0
  106. lib/Azure/GuzzleHttp/HandlerStack.php +273 -0
  107. lib/Azure/GuzzleHttp/MessageFormatter.php +182 -0
  108. lib/Azure/GuzzleHttp/Middleware.php +254 -0
  109. lib/Azure/GuzzleHttp/Pool.php +123 -0
  110. lib/Azure/GuzzleHttp/PrepareBodyMiddleware.php +112 -0
  111. lib/Azure/GuzzleHttp/Promise/AggregateException.php +16 -0
  112. lib/Azure/GuzzleHttp/Promise/CancellationException.php +9 -0
  113. lib/Azure/GuzzleHttp/Promise/Coroutine.php +151 -0
  114. lib/Azure/GuzzleHttp/Promise/EachPromise.php +229 -0
  115. lib/Azure/GuzzleHttp/Promise/FulfilledPromise.php +82 -0
  116. lib/Azure/GuzzleHttp/Promise/Promise.php +273 -0
  117. lib/Azure/GuzzleHttp/Promise/PromiseInterface.php +93 -0
  118. lib/Azure/GuzzleHttp/Promise/PromisorInterface.php +15 -0
  119. lib/Azure/GuzzleHttp/Promise/RejectedPromise.php +87 -0
  120. lib/Azure/GuzzleHttp/Promise/RejectionException.php +47 -0
  121. lib/Azure/GuzzleHttp/Promise/TaskQueue.php +66 -0
  122. lib/Azure/GuzzleHttp/Promise/TaskQueueInterface.php +25 -0
  123. lib/Azure/GuzzleHttp/Promise/functions.php +457 -0
  124. lib/Azure/GuzzleHttp/Promise/functions_include.php +6 -0
  125. lib/Azure/GuzzleHttp/Psr7/AppendStream.php +233 -0
  126. lib/Azure/GuzzleHttp/Psr7/BufferStream.php +137 -0
  127. lib/Azure/GuzzleHttp/Psr7/CachingStream.php +138 -0
  128. lib/Azure/GuzzleHttp/Psr7/DroppingStream.php +42 -0
  129. lib/Azure/GuzzleHttp/Psr7/FnStream.php +149 -0
  130. lib/Azure/GuzzleHttp/Psr7/InflateStream.php +52 -0
  131. lib/Azure/GuzzleHttp/Psr7/LazyOpenStream.php +39 -0
  132. lib/Azure/GuzzleHttp/Psr7/LimitStream.php +155 -0
  133. lib/Azure/GuzzleHttp/Psr7/MessageTrait.php +183 -0
  134. lib/Azure/GuzzleHttp/Psr7/MultipartStream.php +153 -0
  135. lib/Azure/GuzzleHttp/Psr7/NoSeekStream.php +22 -0
  136. lib/Azure/GuzzleHttp/Psr7/PumpStream.php +165 -0
  137. lib/Azure/GuzzleHttp/Psr7/Request.php +142 -0
  138. lib/Azure/GuzzleHttp/Psr7/Response.php +131 -0
  139. lib/Azure/GuzzleHttp/Psr7/ServerRequest.php +346 -0
  140. lib/Azure/GuzzleHttp/Psr7/Stream.php +245 -0
  141. lib/Azure/GuzzleHttp/Psr7/StreamDecoratorTrait.php +149 -0
  142. lib/Azure/GuzzleHttp/Psr7/StreamWrapper.php +121 -0
  143. lib/Azure/GuzzleHttp/Psr7/UploadedFile.php +316 -0
  144. lib/Azure/GuzzleHttp/Psr7/Uri.php +602 -0
  145. lib/Azure/GuzzleHttp/Psr7/functions.php +826 -0
  146. lib/Azure/GuzzleHttp/Psr7/functions_include.php +6 -0
  147. lib/Azure/GuzzleHttp/RedirectMiddleware.php +231 -0
  148. lib/Azure/GuzzleHttp/RequestOptions.php +244 -0
  149. lib/Azure/GuzzleHttp/RetryMiddleware.php +112 -0
  150. lib/Azure/GuzzleHttp/TransferStats.php +126 -0
  151. lib/Azure/GuzzleHttp/UriTemplate.php +241 -0
  152. lib/Azure/GuzzleHttp/functions.php +329 -0
  153. lib/Azure/GuzzleHttp/functions_include.php +6 -0
  154. lib/Azure/MicrosoftAzureStorage/Blob/BlobRestProxy.php +2678 -0
  155. lib/Azure/MicrosoftAzureStorage/Blob/Internal/IBlob.php +502 -0
  156. lib/Azure/MicrosoftAzureStorage/Blob/Models/AccessCondition.php +246 -0
  157. lib/Azure/MicrosoftAzureStorage/Blob/Models/AccessPolicy.php +141 -0
  158. lib/Azure/MicrosoftAzureStorage/Blob/Models/AcquireLeaseOptions.php +66 -0
  159. lib/Azure/MicrosoftAzureStorage/Blob/Models/AcquireLeaseResult.php +88 -0
  160. lib/Azure/MicrosoftAzureStorage/Blob/Models/Blob.php +174 -0
  161. lib/Azure/MicrosoftAzureStorage/Blob/Models/BlobBlockType.php +63 -0
  162. lib/Azure/MicrosoftAzureStorage/Blob/Models/BlobPrefix.php +68 -0
  163. lib/Azure/MicrosoftAzureStorage/Blob/Models/BlobProperties.php +431 -0
  164. lib/Azure/MicrosoftAzureStorage/Blob/Models/BlobServiceOptions.php +65 -0
  165. lib/Azure/MicrosoftAzureStorage/Blob/Models/BlobType.php +42 -0
  166. lib/Azure/MicrosoftAzureStorage/Blob/Models/Block.php +99 -0
  167. lib/Azure/MicrosoftAzureStorage/Blob/Models/BlockList.php +175 -0
  168. lib/Azure/MicrosoftAzureStorage/Blob/Models/BreakLeaseResult.php +86 -0
  169. lib/Azure/MicrosoftAzureStorage/Blob/Models/CommitBlobBlocksOptions.php +258 -0
  170. lib/Azure/MicrosoftAzureStorage/Blob/Models/Container.php +150 -0
  171. lib/Azure/MicrosoftAzureStorage/Blob/Models/ContainerACL.php +218 -0
  172. lib/Azure/MicrosoftAzureStorage/Blob/Models/ContainerProperties.php +95 -0
  173. lib/Azure/MicrosoftAzureStorage/Blob/Models/CopyBlobOptions.php +205 -0
  174. lib/Azure/MicrosoftAzureStorage/Blob/Models/CopyBlobResult.php +123 -0
  175. lib/Azure/MicrosoftAzureStorage/Blob/Models/CreateBlobBlockOptions.php +139 -0
  176. lib/Azure/MicrosoftAzureStorage/Blob/Models/CreateBlobOptions.php +520 -0
  177. lib/Azure/MicrosoftAzureStorage/Blob/Models/CreateBlobPagesOptions.php +122 -0
  178. lib/Azure/MicrosoftAzureStorage/Blob/Models/CreateBlobPagesResult.php +184 -0
  179. lib/Azure/MicrosoftAzureStorage/Blob/Models/CreateBlobSnapshotOptions.php +123 -0
  180. lib/Azure/MicrosoftAzureStorage/Blob/Models/CreateBlobSnapshotResult.php +154 -0
  181. lib/Azure/MicrosoftAzureStorage/Blob/Models/CreateContainerOptions.php +123 -0
  182. lib/Azure/MicrosoftAzureStorage/Blob/Models/DeleteBlobOptions.php +151 -0
  183. lib/Azure/MicrosoftAzureStorage/Blob/Models/DeleteContainerOptions.php +66 -0
  184. lib/Azure/MicrosoftAzureStorage/Blob/Models/GetBlobMetadataOptions.php +122 -0
  185. lib/Azure/MicrosoftAzureStorage/Blob/Models/GetBlobMetadataResult.php +147 -0
  186. lib/Azure/MicrosoftAzureStorage/Blob/Models/GetBlobOptions.php +208 -0
  187. lib/Azure/MicrosoftAzureStorage/Blob/Models/GetBlobPropertiesOptions.php +122 -0
  188. lib/Azure/MicrosoftAzureStorage/Blob/Models/GetBlobPropertiesResult.php +95 -0
  189. lib/Azure/MicrosoftAzureStorage/Blob/Models/GetBlobResult.php +142 -0
  190. lib/Azure/MicrosoftAzureStorage/Blob/Models/GetContainerACLResult.php +145 -0
  191. lib/Azure/MicrosoftAzureStorage/Blob/Models/GetContainerPropertiesResult.php +126 -0
  192. lib/Azure/MicrosoftAzureStorage/Blob/Models/LeaseMode.php +46 -0
  193. lib/Azure/MicrosoftAzureStorage/Blob/Models/ListBlobBlocksOptions.php +187 -0
  194. lib/Azure/MicrosoftAzureStorage/Blob/Models/ListBlobBlocksResult.php +274 -0
  195. lib/Azure/MicrosoftAzureStorage/Blob/Models/ListBlobsOptions.php +237 -0
  196. lib/Azure/MicrosoftAzureStorage/Blob/Models/ListBlobsResult.php +345 -0
  197. lib/Azure/MicrosoftAzureStorage/Blob/Models/ListContainersOptions.php +171 -0
  198. lib/Azure/MicrosoftAzureStorage/Blob/Models/ListContainersResult.php +266 -0
  199. lib/Azure/MicrosoftAzureStorage/Blob/Models/ListPageBlobRangesOptions.php +179 -0
  200. lib/Azure/MicrosoftAzureStorage/Blob/Models/ListPageBlobRangesResult.php +196 -0
  201. lib/Azure/MicrosoftAzureStorage/Blob/Models/PageRange.php +129 -0
  202. lib/Azure/MicrosoftAzureStorage/Blob/Models/PageWriteOption.php +44 -0
  203. lib/Azure/MicrosoftAzureStorage/Blob/Models/PublicAccessType.php +66 -0
  204. lib/Azure/MicrosoftAzureStorage/Blob/Models/SetBlobMetadataOptions.php +95 -0
  205. lib/Azure/MicrosoftAzureStorage/Blob/Models/SetBlobMetadataResult.php +118 -0
  206. lib/Azure/MicrosoftAzureStorage/Blob/Models/SetBlobPropertiesOptions.php +292 -0
  207. lib/Azure/MicrosoftAzureStorage/Blob/Models/SetBlobPropertiesResult.php +149 -0
  208. lib/Azure/MicrosoftAzureStorage/Blob/Models/SetContainerMetadataOptions.php +78 -0
  209. lib/Azure/MicrosoftAzureStorage/Blob/Models/SignedIdentifier.php +103 -0
  210. lib/Azure/MicrosoftAzureStorage/Common/CloudConfigurationManager.php +167 -0
  211. lib/Azure/MicrosoftAzureStorage/Common/Internal/Authentication/IAuthScheme.php +60 -0
  212. lib/Azure/MicrosoftAzureStorage/Common/Internal/Authentication/SharedKeyAuthScheme.php +139 -0
  213. lib/Azure/MicrosoftAzureStorage/Common/Internal/Authentication/StorageAuthScheme.php +213 -0
  214. lib/Azure/MicrosoftAzureStorage/Common/Internal/Authentication/TableSharedKeyLiteAuthScheme.php +121 -0
  215. lib/Azure/MicrosoftAzureStorage/Common/Internal/ConnectionStringParser.php +352 -0
  216. lib/Azure/MicrosoftAzureStorage/Common/Internal/ConnectionStringSource.php +98 -0
  217. lib/Azure/MicrosoftAzureStorage/Common/Internal/FilterableService.php +52 -0
  218. lib/Azure/MicrosoftAzureStorage/Common/Internal/Filters/AuthenticationFilter.php +92 -0
  219. lib/Azure/MicrosoftAzureStorage/Common/Internal/Filters/DateFilter.php +70 -0
  220. lib/Azure/MicrosoftAzureStorage/Common/Internal/Filters/ExponentialRetryPolicy.php +134 -0
  221. lib/Azure/MicrosoftAzureStorage/Common/Internal/Filters/HeadersFilter.php +94 -0
  222. lib/Azure/MicrosoftAzureStorage/Common/Internal/Filters/RetryPolicy.php +66 -0
  223. lib/Azure/MicrosoftAzureStorage/Common/Internal/Filters/RetryPolicyFilter.php +106 -0
  224. lib/Azure/MicrosoftAzureStorage/Common/Internal/Http/HttpCallContext.php +449 -0
  225. lib/Azure/MicrosoftAzureStorage/Common/Internal/HttpFormatter.php +52 -0
  226. lib/Azure/MicrosoftAzureStorage/Common/Internal/IServiceFilter.php +61 -0
  227. lib/Azure/MicrosoftAzureStorage/Common/Internal/InvalidArgumentTypeException.php +57 -0
  228. lib/Azure/MicrosoftAzureStorage/Common/Internal/Logger.php +83 -0
  229. lib/Azure/MicrosoftAzureStorage/Common/Internal/Resources.php +404 -0
  230. lib/Azure/MicrosoftAzureStorage/Common/Internal/RestProxy.php +162 -0
  231. lib/Azure/MicrosoftAzureStorage/Common/Internal/RetryMiddlewareFactory.php +234 -0
  232. lib/Azure/MicrosoftAzureStorage/Common/Internal/Serialization/ISerializer.php +68 -0
BrowserCache_Environment.php CHANGED
@@ -315,9 +315,6 @@ class BrowserCache_Environment {
315
  $rules .= " BrowserMatch \\bMSI[E] !no-gzip !gzip-only-text/html\n";
316
  $rules .= " </IfModule>\n";
317
  }
318
- $rules .= " <IfModule mod_headers.c>\n";
319
- $rules .= " Header append Vary User-Agent env=!dont-vary\n";
320
- $rules .= " </IfModule>\n";
321
  if ( version_compare( $this->_get_server_version(), '2.3.7', '>=' ) ) {
322
  $rules .= " <IfModule mod_filter.c>\n";
323
  }
@@ -393,6 +390,10 @@ class BrowserCache_Environment {
393
  $rules = '';
394
  $headers_rules = '';
395
 
 
 
 
 
396
  if ( $cache_control ) {
397
  $cache_policy = $config->get_string( 'browsercache.' . $section . '.cache.policy' );
398
 
315
  $rules .= " BrowserMatch \\bMSI[E] !no-gzip !gzip-only-text/html\n";
316
  $rules .= " </IfModule>\n";
317
  }
 
 
 
318
  if ( version_compare( $this->_get_server_version(), '2.3.7', '>=' ) ) {
319
  $rules .= " <IfModule mod_filter.c>\n";
320
  }
390
  $rules = '';
391
  $headers_rules = '';
392
 
393
+ if ( $section == 'html' ) {
394
+ $headers_rules .= " Header append Vary User-Agent env=!dont-vary\n";
395
+ }
396
+
397
  if ( $cache_control ) {
398
  $cache_policy = $config->get_string( 'browsercache.' . $section . '.cache.policy' );
399
 
BrowserCache_Plugin.php CHANGED
@@ -115,7 +115,7 @@ class BrowserCache_Plugin {
115
  * @return mixed
116
  */
117
  function ob_callback( $buffer ) {
118
- if ( $buffer != '' && Util_Content::is_html( $buffer ) ) {
119
  $domain_url_regexp = Util_Environment::home_domain_root_url_regexp();
120
 
121
  $buffer = preg_replace_callback(
@@ -214,7 +214,8 @@ class BrowserCache_Plugin {
214
 
215
  $test_url = Util_Environment::remove_query( $url );
216
  foreach ( $exceptions as $exception ) {
217
- if ( trim( $exception ) && preg_match( '~' . $exception . '~', $test_url ) )
 
218
  return false;
219
  }
220
 
115
  * @return mixed
116
  */
117
  function ob_callback( $buffer ) {
118
+ if ( $buffer != '' && Util_Content::is_html_xml( $buffer ) ) {
119
  $domain_url_regexp = Util_Environment::home_domain_root_url_regexp();
120
 
121
  $buffer = preg_replace_callback(
214
 
215
  $test_url = Util_Environment::remove_query( $url );
216
  foreach ( $exceptions as $exception ) {
217
+ $escaped = str_replace( '~', '\~', $exception );
218
+ if ( trim( $exception ) && preg_match( '~' . $escaped . '~', $test_url ) )
219
  return false;
220
  }
221
 
Cache.php CHANGED
@@ -49,9 +49,9 @@ class Cache {
49
  case 'memcached':
50
  if ( class_exists( '\Memcached' ) ) {
51
  $instances[$instance_key] = new Cache_Memcached( $config );
52
- } else if ( class_exists( '\Memcache' ) ) {
53
- $instances[$instance_key] = new Cache_Memcache( $config );
54
- }
55
  break;
56
 
57
  case 'redis':
49
  case 'memcached':
50
  if ( class_exists( '\Memcached' ) ) {
51
  $instances[$instance_key] = new Cache_Memcached( $config );
52
+ } elseif ( class_exists( '\Memcache' ) ) {
53
+ $instances[$instance_key] = new Cache_Memcache( $config );
54
+ }
55
  break;
56
 
57
  case 'redis':
Cache_File_Generic.php CHANGED
@@ -50,7 +50,7 @@ class Cache_File_Generic extends Cache_File {
50
  $dir = dirname( $path );
51
 
52
  if ( !@is_dir( $dir ) ) {
53
- if ( !Util_File::mkdir_from( $dir, W3TC_CACHE_DIR ) )
54
  return false;
55
  }
56
 
@@ -128,7 +128,8 @@ class Cache_File_Generic extends Cache_File {
128
 
129
  }
130
 
131
- @touch( $path_old );
 
132
  }
133
  }
134
  $has_old_data = $exists;
@@ -186,16 +187,15 @@ class Cache_File_Generic extends Cache_File {
186
  return true;
187
 
188
  $old_entry_path = $path . '.old';
189
- if ( @rename( $path, $old_entry_path ) )
190
- return true;
191
-
192
- // if we can delete old entry - do second attempt to store in old-entry file
193
- if ( @unlink( $old_entry_path ) ) {
194
- if ( @rename( $path, $old_entry_path ) )
195
- return true;
196
  }
197
 
198
- return @unlink( $path );
 
199
  }
200
 
201
  /**
@@ -274,7 +274,7 @@ class Cache_File_Generic extends Cache_File {
274
  if ( $entry == '.' || $entry == '..' ) {
275
  continue;
276
  }
277
- if ( preg_match( '/' . $regex . '/', basename( $entry ) ) ) {
278
  Util_File::rmdir( $flush_dir . DIRECTORY_SEPARATOR . $entry );
279
  }
280
  }
50
  $dir = dirname( $path );
51
 
52
  if ( !@is_dir( $dir ) ) {
53
+ if ( !Util_File::mkdir_from_safe( $dir, W3TC_CACHE_DIR ) )
54
  return false;
55
  }
56
 
128
 
129
  }
130
 
131
+ // use old enough time to cause recalculation on next call
132
+ @touch( $path_old, 1479904835 );
133
  }
134
  }
135
  $has_old_data = $exists;
187
  return true;
188
 
189
  $old_entry_path = $path . '.old';
190
+ if ( ! @rename( $path, $old_entry_path ) ) {
191
+ // if we can delete old entry - do second attempt to store in old-entry file
192
+ if ( ! @unlink( $old_entry_path ) || ! @rename( $path, $old_entry_path ) ) {
193
+ return @unlink( $path );
194
+ }
 
 
195
  }
196
 
197
+ @touch( $old_entry_path, 1479904835 );
198
+ return true;
199
  }
200
 
201
  /**
274
  if ( $entry == '.' || $entry == '..' ) {
275
  continue;
276
  }
277
+ if ( preg_match( '~' . $regex . '~', basename( $entry ) ) ) {
278
  Util_File::rmdir( $flush_dir . DIRECTORY_SEPARATOR . $entry );
279
  }
280
  }
Cache_Memcache.php CHANGED
@@ -312,4 +312,10 @@ class Cache_Memcache extends Cache_Base {
312
 
313
  return $v;
314
  }
 
 
 
 
 
 
315
  }
312
 
313
  return $v;
314
  }
315
+
316
+ public function get_item_key( $name ) {
317
+ // memcached doesn't survive spaces in a key
318
+ $key = sprintf( 'w3tc_%s_%d_%s_%s', $this->_host, $this->_blog_id, $this->_module, md5( $name ) );
319
+ return $key;
320
+ }
321
  }
Cache_Memcached.php CHANGED
@@ -384,4 +384,10 @@ class Cache_Memcached extends Cache_Base {
384
 
385
  return $v;
386
  }
 
 
 
 
 
 
387
  }
384
 
385
  return $v;
386
  }
387
+
388
+ public function get_item_key( $name ) {
389
+ // memcached doesn't survive spaces in a key
390
+ $key = sprintf( 'w3tc_%s_%d_%s_%s', $this->_host, $this->_blog_id, $this->_module, md5( $name ) );
391
+ return $key;
392
+ }
393
  }
CdnEngine_Azure.php CHANGED
@@ -26,6 +26,9 @@ class CdnEngine_Azure extends CdnEngine_Base {
26
  ), $config );
27
 
28
  parent::__construct( $config );
 
 
 
29
  }
30
 
31
  /**
@@ -37,7 +40,6 @@ class CdnEngine_Azure extends CdnEngine_Base {
37
  function _init( &$error ) {
38
  if ( empty( $this->_config['user'] ) ) {
39
  $error = 'Empty account name.';
40
-
41
  return false;
42
  }
43
 
@@ -53,17 +55,18 @@ class CdnEngine_Azure extends CdnEngine_Base {
53
  return false;
54
  }
55
 
56
- set_include_path( get_include_path() . PATH_SEPARATOR . W3TC_LIB_DIR );
57
-
58
- require_once 'Microsoft/WindowsAzure/Storage/Blob.php';
59
-
60
- $this->_client = new \Microsoft_WindowsAzure_Storage_Blob(
61
- \Microsoft_WindowsAzure_Storage::URL_CLOUD_BLOB,
62
- $this->_config['user'],
63
- $this->_config['key'],
64
- false,
65
- \Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract::noRetry()
66
- );
 
67
 
68
  return true;
69
  }
@@ -93,12 +96,6 @@ class CdnEngine_Azure extends CdnEngine_Base {
93
  $remote_path = $file['remote_path'];
94
 
95
  $results[] = $this->_upload( $file, $force_rewrite );
96
-
97
- if ( $this->_config['compression'] && $this->_may_gzip( $remote_path ) ) {
98
- $file['remote_path_gzip'] = $remote_path . $this->_gzip_extension;
99
-
100
- $results[] = $this->_upload_gzip( $file, $force_rewrite );
101
- }
102
  }
103
 
104
  return !$this->_is_error( $results );
@@ -121,15 +118,18 @@ class CdnEngine_Azure extends CdnEngine_Base {
121
  W3TC_CDN_RESULT_ERROR, 'Source file not found.', $file );
122
  }
123
 
124
- $md5 = @md5_file( $local_path );
 
125
  $content_md5 = $this->_get_content_md5( $md5 );
126
 
127
  if ( !$force_rewrite ) {
128
  try {
129
- $properties = $this->_client->getBlobProperties( $this->_config['container'], $remote_path );
130
- $size = @filesize( $local_path );
 
 
131
 
132
- if ( $size === (int) $properties->Size && $content_md5 === $properties->ContentMd5 ) {
133
  return $this->_get_result( $local_path, $remote_path,
134
  W3TC_CDN_RESULT_OK, 'File up-to-date.', $file );
135
  }
@@ -143,7 +143,8 @@ class CdnEngine_Azure extends CdnEngine_Base {
143
  ) );
144
 
145
  try {
146
- $this->_client->putBlob( $this->_config['container'], $remote_path, $local_path, array(), null, $headers );
 
147
  } catch ( \Exception $exception ) {
148
  return $this->_get_result( $local_path, $remote_path,
149
  W3TC_CDN_RESULT_ERROR,
@@ -155,70 +156,6 @@ class CdnEngine_Azure extends CdnEngine_Base {
155
  'OK', $file );
156
  }
157
 
158
- /**
159
- * Uploads gzipped file
160
- *
161
- * @param array $file CDN file array
162
- * @param bool $force_rewrite
163
- * @return array
164
- */
165
- function _upload_gzip( $file, $force_rewrite = false ) {
166
- $local_path = $file['local_path'];
167
- $remote_path = $file['remote_path_gzip'];
168
-
169
- if ( !function_exists( 'gzencode' ) ) {
170
- return $this->_get_result( $local_path, $remote_path,
171
- W3TC_CDN_RESULT_ERROR, "GZIP library doesn't exists.", $file );
172
- }
173
-
174
- if ( !file_exists( $local_path ) ) {
175
- return $this->_get_result( $local_path, $remote_path,
176
- W3TC_CDN_RESULT_ERROR, 'Source file not found.', $file );
177
- }
178
-
179
- $contents = @file_get_contents( $local_path );
180
-
181
- if ( $contents === false ) {
182
- return $this->_get_result( $local_path, $remote_path,
183
- W3TC_CDN_RESULT_ERROR, 'Unable to read file.', $file );
184
- }
185
-
186
- $data = gzencode( $contents );
187
- $md5 = md5( $data );
188
- $content_md5 = $this->_get_content_md5( $md5 );
189
-
190
- if ( !$force_rewrite ) {
191
- try {
192
- $properties = $this->_client->getBlobProperties( $this->_config['container'], $remote_path );
193
- $size = @filesize( $local_path );
194
-
195
- if ( $size === (int) $properties->Size && $content_md5 === $properties->ContentMd5 ) {
196
- return $this->_get_result( $local_path, $remote_path,
197
- W3TC_CDN_RESULT_OK, 'File up-to-date.', $file );
198
- }
199
- } catch ( \Exception $exception ) {
200
- }
201
- }
202
-
203
- $headers = $this->_get_headers( $file );
204
- $headers = array_merge( $headers, array(
205
- 'Content-MD5' => $content_md5,
206
- 'Content-Encoding' => 'gzip'
207
- ) );
208
-
209
- try {
210
- $this->_client->putBlobData( $this->_config['container'], $remote_path, $data, array(), null, $headers );
211
- } catch ( \Exception $exception ) {
212
- return $this->_get_result( $local_path, $remote_path,
213
- W3TC_CDN_RESULT_ERROR,
214
- sprintf( 'Unable to put blob (%s).', $exception->getMessage() ),
215
- $file );
216
- }
217
-
218
- return $this->_get_result( $local_path, $remote_path,
219
- W3TC_CDN_RESULT_OK, 'OK', $file );
220
- }
221
-
222
  /**
223
  * Deletes files from storage
224
  *
@@ -249,23 +186,6 @@ class CdnEngine_Azure extends CdnEngine_Base {
249
  sprintf( 'Unable to delete blob (%s).', $exception->getMessage() ),
250
  $file );
251
  }
252
-
253
- if ( $this->_config['compression'] ) {
254
- $remote_path_gzip = $remote_path . $this->_gzip_extension;
255
-
256
- try {
257
- $this->_client->deleteBlob( $this->_config['container'], $remote_path_gzip );
258
- $results[] = $this->_get_result( $local_path,
259
- $remote_path_gzip, W3TC_CDN_RESULT_OK, 'OK',
260
- $file );
261
- } catch ( \Exception $exception ) {
262
- $results[] = $this->_get_result( $local_path,
263
- $remote_path_gzip, W3TC_CDN_RESULT_ERROR,
264
- sprintf( 'Unable to delete blob (%s).',
265
- $exception->getMessage() ),
266
- $file );
267
- }
268
- }
269
  }
270
 
271
  return !$this->_is_error( $results );
@@ -298,8 +218,8 @@ class CdnEngine_Azure extends CdnEngine_Base {
298
 
299
  $container = null;
300
 
301
- foreach ( (array) $containers as $_container ) {
302
- if ( $_container->Name == $this->_config['container'] ) {
303
  $container = $_container;
304
  break;
305
  }
@@ -312,21 +232,42 @@ class CdnEngine_Azure extends CdnEngine_Base {
312
  }
313
 
314
  try {
315
- $this->_client->putBlobData( $this->_config['container'], $string, $string );
316
  } catch ( \Exception $exception ) {
317
- $error = sprintf( 'Unable to put blob data (%s).', $exception->getMessage() );
 
 
318
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  return false;
320
  }
321
 
322
  try {
323
- $data = $this->_client->getBlobData( $this->_config['container'], $string );
 
 
324
  } catch ( \Exception $exception ) {
325
  $error = sprintf( 'Unable to get blob data (%s).', $exception->getMessage() );
326
-
327
  return false;
328
  }
329
 
 
330
  if ( $data != $string ) {
331
  try {
332
  $this->_client->deleteBlob( $this->_config['container'], $string );
@@ -334,7 +275,6 @@ class CdnEngine_Azure extends CdnEngine_Base {
334
  }
335
 
336
  $error = 'Blob datas are not equal.';
337
-
338
  return false;
339
  }
340
 
@@ -404,8 +344,11 @@ class CdnEngine_Azure extends CdnEngine_Base {
404
  }
405
 
406
  try {
407
- $this->_client->createContainer( $this->_config['container'] );
408
- $this->_client->setContainerAcl( $this->_config['container'], \Microsoft_WindowsAzure_Storage_Blob::ACL_PUBLIC_BLOB );
 
 
 
409
  } catch ( \Exception $exception ) {
410
  $error = sprintf( 'Unable to create container: %s (%s)', $this->_config['container'], $exception->getMessage() );
411
 
@@ -450,7 +393,7 @@ class CdnEngine_Azure extends CdnEngine_Base {
450
  * @param array $file CDN file array
451
  * @return array
452
  */
453
- function _get_headers( $file ) {
454
  $allowed_headers = array(
455
  'Content-Length',
456
  'Content-Type',
26
  ), $config );
27
 
28
  parent::__construct( $config );
29
+
30
+ require_once W3TC_LIB_DIR . DIRECTORY_SEPARATOR . 'Azure' .
31
+ DIRECTORY_SEPARATOR . 'loader.php';
32
  }
33
 
34
  /**
40
  function _init( &$error ) {
41
  if ( empty( $this->_config['user'] ) ) {
42
  $error = 'Empty account name.';
 
43
  return false;
44
  }
45
 
55
  return false;
56
  }
57
 
58
+ try {
59
+ $connectionString = 'DefaultEndpointsProtocol=https;AccountName=' .
60
+ $this->_config['user'] .
61
+ ';AccountKey=' . $this->_config['key'];
62
+
63
+ $this->_client = \MicrosoftAzure\Storage\Common\ServicesBuilder::getInstance()->createBlobService(
64
+ $connectionString);
65
+ } catch ( \Exception $ex ) {
66
+ $error = $ex->getMessage();
67
+ return false;
68
+ }
69
+
70
 
71
  return true;
72
  }
96
  $remote_path = $file['remote_path'];
97
 
98
  $results[] = $this->_upload( $file, $force_rewrite );
 
 
 
 
 
 
99
  }
100
 
101
  return !$this->_is_error( $results );
118
  W3TC_CDN_RESULT_ERROR, 'Source file not found.', $file );
119
  }
120
 
121
+ $contents = @file_get_contents( $local_path );
122
+ $md5 = md5( $contents ); // @md5_file( $local_path );
123
  $content_md5 = $this->_get_content_md5( $md5 );
124
 
125
  if ( !$force_rewrite ) {
126
  try {
127
+ $propertiesResult = $this->_client->getBlobProperties( $this->_config['container'], $remote_path );
128
+ $p = $propertiesResult->getProperties();
129
+
130
+ $local_size = @filesize( $local_path );
131
 
132
+ if ( $local_size == $p->getContentLength() && $content_md5 === $p->getContentMD5() ) {
133
  return $this->_get_result( $local_path, $remote_path,
134
  W3TC_CDN_RESULT_OK, 'File up-to-date.', $file );
135
  }
143
  ) );
144
 
145
  try {
146
+ // $headers
147
+ $this->_client->createBlockBlob( $this->_config['container'], $remote_path, $contents );
148
  } catch ( \Exception $exception ) {
149
  return $this->_get_result( $local_path, $remote_path,
150
  W3TC_CDN_RESULT_ERROR,
156
  'OK', $file );
157
  }
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  /**
160
  * Deletes files from storage
161
  *
186
  sprintf( 'Unable to delete blob (%s).', $exception->getMessage() ),
187
  $file );
188
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  }
190
 
191
  return !$this->_is_error( $results );
218
 
219
  $container = null;
220
 
221
+ foreach ( $containers->getContainers() as $_container ) {
222
+ if ( $_container->getName() == $this->_config['container'] ) {
223
  $container = $_container;
224
  break;
225
  }
232
  }
233
 
234
  try {
235
+ $this->_client->createBlockBlob( $this->_config['container'], $string, $string );
236
  } catch ( \Exception $exception ) {
237
+ $error = sprintf( 'Unable to create blob (%s).', $exception->getMessage() );
238
+ return false;
239
+ }
240
 
241
+ try {
242
+ $propertiesResult = $this->_client->getBlobProperties( $this->_config['container'], $string );
243
+ $p = $propertiesResult->getProperties();
244
+ $size = $p->getContentLength();
245
+ $md5 = $p->getContentMD5();
246
+ } catch ( \Exception $exception ) {
247
+ $error = sprintf( 'Unable to get blob properties (%s).', $exception->getMessage() );
248
+ return false;
249
+ }
250
+
251
+ if ( $size != strlen( $string ) || $this->_get_content_md5( md5( $string ) ) != $md5 ) {
252
+ try {
253
+ $this->_client->deleteBlob( $this->_config['container'], $string );
254
+ } catch ( \Exception $exception ) {
255
+ }
256
+
257
+ $error = 'Blob data properties are not equal.';
258
  return false;
259
  }
260
 
261
  try {
262
+ $getBlob = $this->_client->getBlob( $this->_config['container'], $string );
263
+ $dataStream = $getBlob->getContentStream();
264
+ $data = stream_get_contents( $dataStream );
265
  } catch ( \Exception $exception ) {
266
  $error = sprintf( 'Unable to get blob data (%s).', $exception->getMessage() );
 
267
  return false;
268
  }
269
 
270
+
271
  if ( $data != $string ) {
272
  try {
273
  $this->_client->deleteBlob( $this->_config['container'], $string );
275
  }
276
 
277
  $error = 'Blob datas are not equal.';
 
278
  return false;
279
  }
280
 
344
  }
345
 
346
  try {
347
+ $createContainerOptions = new \MicrosoftAzure\Storage\Blob\Models\CreateContainerOptions();
348
+ $createContainerOptions->setPublicAccess(
349
+ \MicrosoftAzure\Storage\Blob\Models\PublicAccessType::CONTAINER_AND_BLOBS );
350
+
351
+ $this->_client->createContainer( $this->_config['container'], $createContainerOptions );
352
  } catch ( \Exception $exception ) {
353
  $error = sprintf( 'Unable to create container: %s (%s)', $this->_config['container'], $exception->getMessage() );
354
 
393
  * @param array $file CDN file array
394
  * @return array
395
  */
396
+ function _get_headers( $file, $block_expires = false ) {
397
  $allowed_headers = array(
398
  'Content-Length',
399
  'Content-Type',
CdnEngine_GoogleDrive.php CHANGED
@@ -30,12 +30,17 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
30
 
31
  try {
32
  $this->_init_service( $config['access_token'] );
33
- } catch ( \Exception $e ) {}
 
 
34
  }
35
 
36
 
37
 
38
  private function _init_service( $access_token ) {
 
 
 
39
  $client = new \W3TCG_Google_Client();
40
  $client->setClientId( $this->_client_id );
41
  $client->setAccessToken( $access_token );
@@ -72,6 +77,9 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
72
  * @return boolean
73
  */
74
  function upload( $files, &$results, $force_rewrite = false, $timeout_time = NULL ) {
 
 
 
75
  $allow_refresh_token = true;
76
  $result = true;
77
 
30
 
31
  try {
32
  $this->_init_service( $config['access_token'] );
33
+ } catch ( \Exception $e ) {
34
+ $this->_service = null;
35
+ }
36
  }
37
 
38
 
39
 
40
  private function _init_service( $access_token ) {
41
+ if ( empty( $this->_client_id ) || empty( $access_token ) )
42
+ throw new \Exception('service not configured');
43
+
44
  $client = new \W3TCG_Google_Client();
45
  $client->setClientId( $this->_client_id );
46
  $client->setAccessToken( $access_token );
77
  * @return boolean
78
  */
79
  function upload( $files, &$results, $force_rewrite = false, $timeout_time = NULL ) {
80
+ if ( is_null( $this->_service ) )
81
+ return false;
82
+
83
  $allow_refresh_token = true;
84
  $result = true;
85
 
Cdn_Core.php CHANGED
@@ -358,7 +358,7 @@ class Cdn_Core {
358
  'container' => $this->_config->get_string( 'cdn.azure.container' ),
359
  'cname' => $this->_config->get_array( 'cdn.azure.cname' ),
360
  'ssl' => $this->_config->get_string( 'cdn.azure.ssl' ),
361
- 'compression' => $compression
362
  );
363
  break;
364
 
358
  'container' => $this->_config->get_string( 'cdn.azure.container' ),
359
  'cname' => $this->_config->get_array( 'cdn.azure.cname' ),
360
  'ssl' => $this->_config->get_string( 'cdn.azure.ssl' ),
361
+ 'compression' => false
362
  );
363
  break;
364
 
Cdn_Plugin.php CHANGED
@@ -293,7 +293,7 @@ class Cdn_Plugin {
293
  * @return string
294
  */
295
  function ob_callback( $buffer ) {
296
- if ( $buffer != '' && Util_Content::is_html( $buffer ) ) {
297
  if ( $this->can_cdn2( $buffer ) ) {
298
  $srcset_helper = new _Cdn_Plugin_ContentFilter();
299
  $buffer = $srcset_helper->replace_all_links( $buffer );
@@ -613,6 +613,8 @@ class Cdn_Plugin {
613
 
614
  foreach ( $reject_uri as $expr ) {
615
  $expr = trim( $expr );
 
 
616
  if ( $expr != '' && preg_match( '~' . $expr . '~i', $_SERVER['REQUEST_URI'] ) ) {
617
  return false;
618
  }
@@ -630,7 +632,7 @@ class Cdn_Plugin {
630
  * @return boolean
631
  */
632
  private function _check_logged_in_role_allowed() {
633
- global $current_user;
634
 
635
  if ( !is_user_logged_in() )
636
  return true;
@@ -994,27 +996,49 @@ class _Cdn_Plugin_ContentFilter {
994
 
995
  if ( $this->_config->get_boolean( 'cdn.custom.enable' ) ) {
996
  $masks = $this->_config->get_array( 'cdn.custom.files' );
997
- $masks = array_map( array( '\W3TC\Cdn_Util', 'replace_folder_placeholders' ), $masks );
998
  $masks = array_map( array( '\W3TC\Util_Environment', 'parse_path' ), $masks );
999
 
1000
  if ( count( $masks ) ) {
1001
- $mask_regexps = array();
 
 
1002
 
1003
  foreach ( $masks as $mask ) {
1004
- if ( $mask != '' ) {
1005
- $mask = Util_Environment::normalize_file( $mask );
1006
- $mask_regexps[] = Cdn_Util::get_regexp_by_mask( $mask );
 
 
 
 
 
 
 
 
 
1007
  }
1008
  }
1009
 
1010
- $regexps[] = '~(["\'(=])\s*((' . $domain_url_regexp .
1011
- ')?(' . Util_Environment::preg_quote( $site_path ) .
1012
- '(' . implode( '|', $mask_regexps ) . ')([^"\'() >]*)))~i';
1013
- if ( $site_domain_url_regexp )
1014
- $regexps[] = '~(["\'(=])\s*((' .
1015
- $site_domain_url_regexp . ')?(' .
1016
- Util_Environment::preg_quote( $site_path ) . '(' .
1017
- implode( '|', $mask_regexps ) . ')([^"\'() >]*)))~i';
 
 
 
 
 
 
 
 
 
 
 
1018
  }
1019
  }
1020
 
293
  * @return string
294
  */
295
  function ob_callback( $buffer ) {
296
+ if ( $buffer != '' && Util_Content::is_html_xml( $buffer ) ) {
297
  if ( $this->can_cdn2( $buffer ) ) {
298
  $srcset_helper = new _Cdn_Plugin_ContentFilter();
299
  $buffer = $srcset_helper->replace_all_links( $buffer );
613
 
614
  foreach ( $reject_uri as $expr ) {
615
  $expr = trim( $expr );
616
+ $expr = str_replace( '~', '\~', $expr );
617
+
618
  if ( $expr != '' && preg_match( '~' . $expr . '~i', $_SERVER['REQUEST_URI'] ) ) {
619
  return false;
620
  }
632
  * @return boolean
633
  */
634
  private function _check_logged_in_role_allowed() {
635
+ $current_user = wp_get_current_user();
636
 
637
  if ( !is_user_logged_in() )
638
  return true;
996
 
997
  if ( $this->_config->get_boolean( 'cdn.custom.enable' ) ) {
998
  $masks = $this->_config->get_array( 'cdn.custom.files' );
999
+ $masks = array_map( array( '\W3TC\Cdn_Util', 'replace_folder_placeholders_to_uri' ), $masks );
1000
  $masks = array_map( array( '\W3TC\Util_Environment', 'parse_path' ), $masks );
1001
 
1002
  if ( count( $masks ) ) {
1003
+ $custom_regexps_urls = array();
1004
+ $custom_regexps_uris = array();
1005
+ $custom_regexps_docroot_related = array();
1006
 
1007
  foreach ( $masks as $mask ) {
1008
+ if ( !empty( $mask ) ) {
1009
+ if ( Util_Environment::is_url( $mask ) ) {
1010
+ $custom_regexps_urls[] = Cdn_Util::get_regexp_by_mask( $mask );
1011
+ } elseif ( substr( $mask, 0, 1 ) == '/' ) { // uri
1012
+ $custom_regexps_uris[] = Cdn_Util::get_regexp_by_mask( $mask );
1013
+ } else {
1014
+ $file = Util_Environment::normalize_path( $mask ); // \ -> backspaces
1015
+ $file = str_replace( Util_Environment::site_root(), '', $file );
1016
+ $file = ltrim( $file, '/' );
1017
+
1018
+ $custom_regexps_docroot_related[] = Cdn_Util::get_regexp_by_mask( $mask );
1019
+ }
1020
  }
1021
  }
1022
 
1023
+ if ( count( $custom_regexps_urls ) > 0 ) {
1024
+ foreach ( $custom_regexps_urls as $regexp )
1025
+ $regexps[] = '~(["\'(=])\s*((' . $regexp . ')?(()([^"\'() >]*)))~i';
1026
+ }
1027
+ if ( count( $custom_regexps_uris ) > 0 ) {
1028
+ $regexps[] = '~(["\'(=])\s*((' . $domain_url_regexp .
1029
+ ')?((' . implode( '|', $custom_regexps_uris ) . ')([^"\'() >]*)))~i';
1030
+ }
1031
+
1032
+ if ( count( $custom_regexps_docroot_related ) > 0) {
1033
+ $regexps[] = '~(["\'(=])\s*((' . $domain_url_regexp .
1034
+ ')?(' . Util_Environment::preg_quote( $site_path ) .
1035
+ '(' . implode( '|', $custom_regexps_docroot_related ) . ')([^"\'() >]*)))~i';
1036
+ if ( $site_domain_url_regexp )
1037
+ $regexps[] = '~(["\'(=])\s*((' .
1038
+ $site_domain_url_regexp . ')?(' .
1039
+ Util_Environment::preg_quote( $site_path ) . '(' .
1040
+ implode( '|', $custom_regexps_docroot_related ) . ')([^"\'() >]*)))~i';
1041
+ }
1042
  }
1043
  }
1044
 
Cdn_RackSpace_Api_CaCert.pem → Cdn_RackSpace_Api_CaCert-example.pem RENAMED
File without changes
Cdn_RackSpace_Api_Cdn.php CHANGED
@@ -81,8 +81,8 @@ class Cdn_RackSpace_Api_Cdn {
81
  $url_base = $this->_access_region_descriptor['cdn.publicURL'];
82
 
83
  $result = wp_remote_get( $url_base . $uri . '?format=json', array(
84
- 'headers' => 'X-Auth-Token: ' . $this->_access_token,
85
- 'sslcertificates' => dirname( __FILE__ ) . '/Cdn_RackSpace_Api_CaCert.pem'
86
  ) );
87
 
88
  $r = self::_decode_response_json( $result );
@@ -104,7 +104,7 @@ class Cdn_RackSpace_Api_Cdn {
104
  $result = wp_remote_post( $url_base . $uri, array(
105
  'headers' => $headers,
106
  'body' => $body,
107
- 'sslcertificates' => dirname( __FILE__ ) . '/Cdn_RackSpace_Api_CaCert.pem',
108
  'method' => 'PATCH'
109
  ) );
110
 
@@ -129,8 +129,8 @@ class Cdn_RackSpace_Api_Cdn {
129
 
130
  $result = wp_remote_post( $url_base . $uri, array(
131
  'headers' => $headers,
132
- 'body' => $body,
133
- 'sslcertificates' => dirname( __FILE__ ) . '/Cdn_RackSpace_Api_CaCert.pem'
134
  ) );
135
 
136
  $r = self::_decode_response( $result );
@@ -154,7 +154,7 @@ class Cdn_RackSpace_Api_Cdn {
154
 
155
  $result = wp_remote_post( $url_base . $uri, array(
156
  'headers' => $headers,
157
- 'sslcertificates' => dirname( __FILE__ ) . '/Cdn_RackSpace_Api_CaCert.pem',
158
  'method' => 'DELETE'
159
  ) );
160
 
@@ -164,7 +164,7 @@ class Cdn_RackSpace_Api_Cdn {
164
  }
165
 
166
  $new_object = call_user_func( $this->_new_access_required );
167
- return $new_object->_wp_remote_delete( $uri, $body );
168
  }
169
 
170
 
@@ -176,6 +176,12 @@ class Cdn_RackSpace_Api_Cdn {
176
  if ( empty( $result['body'] ) )
177
  $response_json = array();
178
  else {
 
 
 
 
 
 
179
  $response_json = @json_decode( $result['body'], true );
180
  if ( is_null( $response_json ) )
181
  throw new \Exception(
@@ -189,7 +195,10 @@ class Cdn_RackSpace_Api_Cdn {
189
  $result['response']['code'] != '204' )
190
  throw new \Exception( $result['body'] );
191
 
192
- return array( 'response_json' => $response_json, 'auth_required' => false );
 
 
 
193
  }
194
 
195
 
@@ -202,6 +211,13 @@ class Cdn_RackSpace_Api_Cdn {
202
  $result['response']['code'] != '201' &&
203
  $result['response']['code'] != '202' &&
204
  $result['response']['code'] != '204' ) {
 
 
 
 
 
 
 
205
  // try to decode response
206
  $response_json = @json_decode( $result['body'], true );
207
  if ( is_null( $response_json ) ||
81
  $url_base = $this->_access_region_descriptor['cdn.publicURL'];
82
 
83
  $result = wp_remote_get( $url_base . $uri . '?format=json', array(
84
+ 'headers' => 'X-Auth-Token: ' . $this->_access_token
85
+ //'sslcertificates' => dirname( __FILE__ ) . '/Cdn_RackSpace_Api_CaCert.pem'
86
  ) );
87
 
88
  $r = self::_decode_response_json( $result );
104
  $result = wp_remote_post( $url_base . $uri, array(
105
  'headers' => $headers,
106
  'body' => $body,
107
+ //'sslcertificates' => dirname( __FILE__ ) . '/Cdn_RackSpace_Api_CaCert.pem',
108
  'method' => 'PATCH'
109
  ) );
110
 
129
 
130
  $result = wp_remote_post( $url_base . $uri, array(
131
  'headers' => $headers,
132
+ 'body' => $body
133
+ //'sslcertificates' => dirname( __FILE__ ) . '/Cdn_RackSpace_Api_CaCert.pem'
134
  ) );
135
 
136
  $r = self::_decode_response( $result );
154
 
155
  $result = wp_remote_post( $url_base . $uri, array(
156
  'headers' => $headers,
157
+ //'sslcertificates' => dirname( __FILE__ ) . '/Cdn_RackSpace_Api_CaCert.pem',
158
  'method' => 'DELETE'
159
  ) );
160
 
164
  }
165
 
166
  $new_object = call_user_func( $this->_new_access_required );
167
+ return $new_object->_wp_remote_delete( $uri, array() );
168
  }
169
 
170
 
176
  if ( empty( $result['body'] ) )
177
  $response_json = array();
178
  else {
179
+ if ( $result['body'] == 'Unauthorized' )
180
+ return array(
181
+ 'response_json' => array(),
182
+ 'auth_required' => true
183
+ );
184
+
185
  $response_json = @json_decode( $result['body'], true );
186
  if ( is_null( $response_json ) )
187
  throw new \Exception(
195
  $result['response']['code'] != '204' )
196
  throw new \Exception( $result['body'] );
197
 
198
+ return array(
199
+ 'response_json' => $response_json,
200
+ 'auth_required' => false
201
+ );
202
  }
203
 
204
 
211
  $result['response']['code'] != '201' &&
212
  $result['response']['code'] != '202' &&
213
  $result['response']['code'] != '204' ) {
214
+
215
+ if ( $result['response']['message'] == 'Unauthorized' )
216
+ return array(
217
+ 'response_json' => array(),
218
+ 'auth_required' => true
219
+ );
220
+
221
  // try to decode response
222
  $response_json = @json_decode( $result['body'], true );
223
  if ( is_null( $response_json ) ||
Cdn_RackSpace_Api_CloudFiles.php CHANGED
@@ -69,8 +69,8 @@ class Cdn_RackSpace_Api_CloudFiles {
69
  $result = wp_remote_post( $url_base . $uri . '?format=json', array(
70
  'headers' => $headers,
71
  'body' => $body,
72
- 'sslcertificates' => dirname( __FILE__ ) .
73
- '/Cdn_RackSpace_Api_CaCert.pem',
74
  'timeout' => 120,
75
  'method' => 'PUT'
76
  ) );
@@ -92,8 +92,8 @@ class Cdn_RackSpace_Api_CloudFiles {
92
 
93
  $result = wp_remote_get( $url_base . $uri . '?format=json', array(
94
  'headers' => array( 'X-Auth-Token' => $this->_access_token ),
95
- 'sslcertificates' => dirname( __FILE__ ) .
96
- '/Cdn_RackSpace_Api_CaCert.pem',
97
  'method' => 'HEAD'
98
  ) );
99
 
@@ -117,8 +117,8 @@ class Cdn_RackSpace_Api_CloudFiles {
117
 
118
  $result = wp_remote_post( $url_base . $uri . '?format=json', array(
119
  'headers' => array( 'X-Auth-Token' => $this->_access_token ),
120
- 'sslcertificates' => dirname( __FILE__ ) .
121
- '/Cdn_RackSpace_Api_CaCert.pem',
122
  'method' => 'DELETE'
123
  ) );
124
 
@@ -140,10 +140,17 @@ class Cdn_RackSpace_Api_CloudFiles {
140
  if ( $result['response']['code'] != '200' &&
141
  $result['response']['code'] != '201' &&
142
  $result['response']['code'] != '202' &&
143
- $result['response']['code'] != '204' )
 
 
 
 
 
 
144
  throw new \Exception(
145
  'Failed to reach API endpoint, got unexpected response ' .
146
  $result['response']['message'] );
 
147
 
148
  return array( 'auth_required' => false );
149
  }
69
  $result = wp_remote_post( $url_base . $uri . '?format=json', array(
70
  'headers' => $headers,
71
  'body' => $body,
72
+ //'sslcertificates' => dirname( __FILE__ ) .
73
+ //'/Cdn_RackSpace_Api_CaCert.pem',
74
  'timeout' => 120,
75
  'method' => 'PUT'
76
  ) );
92
 
93
  $result = wp_remote_get( $url_base . $uri . '?format=json', array(
94
  'headers' => array( 'X-Auth-Token' => $this->_access_token ),
95
+ //'sslcertificates' => dirname( __FILE__ ) .
96
+ //'/Cdn_RackSpace_Api_CaCert.pem',
97
  'method' => 'HEAD'
98
  ) );
99
 
117
 
118
  $result = wp_remote_post( $url_base . $uri . '?format=json', array(
119
  'headers' => array( 'X-Auth-Token' => $this->_access_token ),
120
+ //'sslcertificates' => dirname( __FILE__ ) .
121
+ //'/Cdn_RackSpace_Api_CaCert.pem',
122
  'method' => 'DELETE'
123
  ) );
124
 
140
  if ( $result['response']['code'] != '200' &&
141
  $result['response']['code'] != '201' &&
142
  $result['response']['code'] != '202' &&
143
+ $result['response']['code'] != '204' ) {
144
+
145
+ if ( $result['response']['message'] == 'Unauthorized' )
146
+ return array(
147
+ 'auth_required' => true
148
+ );
149
+
150
  throw new \Exception(
151
  'Failed to reach API endpoint, got unexpected response ' .
152
  $result['response']['message'] );
153
+ }
154
 
155
  return array( 'auth_required' => false );
156
  }
Cdn_RackSpace_Api_CloudFilesCdn.php CHANGED
@@ -42,8 +42,8 @@ class Cdn_RackSpace_Api_CloudFilesCdn {
42
  $url_base = $this->_access_region_descriptor['object-cdn.publicURL'];
43
 
44
  $result = wp_remote_get( $url_base . $uri . '?format=json', array(
45
- 'headers' => 'X-Auth-Token: ' . $this->_access_token,
46
- 'sslcertificates' => dirname( __FILE__ ) . '/Cdn_RackSpace_Api_CaCert.pem'
47
  ) );
48
 
49
  $r = self::_decode_response_json( $result );
@@ -63,7 +63,7 @@ class Cdn_RackSpace_Api_CloudFilesCdn {
63
 
64
  $result = wp_remote_get( $url_base . $uri . '?format=json', array(
65
  'headers' => 'X-Auth-Token: ' . $this->_access_token,
66
- 'sslcertificates' => dirname( __FILE__ ) . '/Cdn_RackSpace_Api_CaCert.pem',
67
  'method' => 'HEAD'
68
  ) );
69
 
@@ -86,7 +86,7 @@ class Cdn_RackSpace_Api_CloudFilesCdn {
86
  $result = wp_remote_post( $url_base . $uri, array(
87
  'headers' => $headers,
88
  'body' => $body,
89
- 'sslcertificates' => dirname( __FILE__ ) . '/Cdn_RackSpace_Api_CaCert.pem',
90
  'method' => 'PUT'
91
  ) );
92
 
@@ -133,10 +133,17 @@ class Cdn_RackSpace_Api_CloudFilesCdn {
133
  if ( $result['response']['code'] != '200' &&
134
  $result['response']['code'] != '201' &&
135
  $result['response']['code'] != '202' &&
136
- $result['response']['code'] != '204' )
 
 
 
 
 
 
137
  throw new \Exception(
138
  'Failed to reach API endpoint, got unexpected response ' .
139
  $result['response']['message'] );
 
140
 
141
  return array( 'auth_required' => false );
142
  }
42
  $url_base = $this->_access_region_descriptor['object-cdn.publicURL'];
43
 
44
  $result = wp_remote_get( $url_base . $uri . '?format=json', array(
45
+ 'headers' => 'X-Auth-Token: ' . $this->_access_token
46
+ //'sslcertificates' => dirname( __FILE__ ) . '/Cdn_RackSpace_Api_CaCert.pem'
47
  ) );
48
 
49
  $r = self::_decode_response_json( $result );
63
 
64
  $result = wp_remote_get( $url_base . $uri . '?format=json', array(
65
  'headers' => 'X-Auth-Token: ' . $this->_access_token,
66
+ //'sslcertificates' => dirname( __FILE__ ) . '/Cdn_RackSpace_Api_CaCert.pem',
67
  'method' => 'HEAD'
68
  ) );
69
 
86
  $result = wp_remote_post( $url_base . $uri, array(
87
  'headers' => $headers,
88
  'body' => $body,
89
+ //'sslcertificates' => dirname( __FILE__ ) . '/Cdn_RackSpace_Api_CaCert.pem',
90
  'method' => 'PUT'
91
  ) );
92
 
133
  if ( $result['response']['code'] != '200' &&
134
  $result['response']['code'] != '201' &&
135
  $result['response']['code'] != '202' &&
136
+ $result['response']['code'] != '204' ) {
137
+
138
+ if ( $result['response']['message'] == 'Unauthorized' )
139
+ return array(
140
+ 'auth_required' => true
141
+ );
142
+
143
  throw new \Exception(
144
  'Failed to reach API endpoint, got unexpected response ' .
145
  $result['response']['message'] );
146
+ }
147
 
148
  return array( 'auth_required' => false );
149
  }
Cdn_RackSpace_Api_Tokens.php CHANGED
@@ -18,8 +18,8 @@ class Cdn_RackSpace_Api_Tokens {
18
  'Accept' => 'application/json',
19
  'Content-Type' => 'application/json'
20
  ),
21
- 'sslcertificates' => dirname( __FILE__ ) .
22
- '/Cdn_RackSpace_Api_CaCert.pem',
23
  'body' => json_encode( $request_json )
24
  )
25
  );
18
  'Accept' => 'application/json',
19
  'Content-Type' => 'application/json'
20
  ),
21
+ //'sslcertificates' => dirname( __FILE__ ) .
22
+ //'/Cdn_RackSpace_Api_CaCert.pem',
23
  'body' => json_encode( $request_json )
24
  )
25
  );
Cdn_Util.php CHANGED
@@ -221,4 +221,23 @@ class Cdn_Util {
221
 
222
  return $file;
223
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  }
221
 
222
  return $file;
223
  }
224
+
225
+ static function replace_folder_placeholders_to_uri( $file ) {
226
+ static $content_uri, $plugins_uri, $uploads_uri;
227
+ if ( empty( $content_uri ) ) {
228
+ $content_uri = Util_Environment::url_to_uri( content_url() );
229
+ $plugins_uri = Util_Environment::url_to_uri( plugins_url() );
230
+
231
+ $upload_dir = Util_Environment::wp_upload_dir();
232
+ if ( isset( $upload_dir['baseurl'] ) )
233
+ $uploads_uri = $upload_dir['baseurl'];
234
+ else
235
+ $uploads_uri = '';
236
+ }
237
+ $file = str_replace( '{wp_content_dir}', $content_uri, $file );
238
+ $file = str_replace( '{plugins_dir}', $plugins_uri, $file );
239
+ $file = str_replace( '{uploads_dir}', $uploads_uri, $file );
240
+
241
+ return $file;
242
+ }
243
  }
Cli.php CHANGED
@@ -2,18 +2,71 @@
2
  namespace W3TC;
3
 
4
  /**
5
- * The W3 Total Cache plugin
6
  *
7
  * @package wp-cli
8
  * @subpackage commands/third-party
9
  */
10
  class W3TotalCache_Command extends \WP_CLI_Command {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  /**
13
- * Clear something from the cache
14
  *
15
- * @param array $args
16
- * @param array $vars
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  */
18
  function flush( $args = array(), $vars = array() ) {
19
  $args = array_unique( $args );
@@ -22,6 +75,26 @@ class W3TotalCache_Command extends \WP_CLI_Command {
22
  $cache_type = array_shift( $args );
23
 
24
  switch ( $cache_type ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  case 'db':
26
  case 'database':
27
  try {
@@ -57,12 +130,10 @@ class W3TotalCache_Command extends \WP_CLI_Command {
57
  break;
58
 
59
  case 'post':
60
- default:
61
  if ( isset( $vars['post_id'] ) ) {
62
  if ( is_numeric( $vars['post_id'] ) ) {
63
  try {
64
- $w3_cacheflush = Dispatcher::component( 'CacheFlush' );
65
- $w3_cacheflush->flush_post( $vars['post_id'] );
66
  }
67
  catch ( \Exception $e ) {
68
  \WP_CLI::error( __( 'Flushing the page from cache failed.', 'w3-total-cache' ) );
@@ -71,48 +142,164 @@ class W3TotalCache_Command extends \WP_CLI_Command {
71
  } else {
72
  \WP_CLI::error( __( 'This is not a valid post id.', 'w3-total-cache' ) );
73
  }
74
-
75
- w3tc_flush_post( $vars['post_id'] );
76
  }
77
  elseif ( isset( $vars['permalink'] ) ) {
78
- $id = url_to_postid( $vars['permalink'] );
79
-
80
- if ( is_numeric( $id ) ) {
81
- try {
82
- $w3_cacheflush = Dispatcher::component( 'CacheFlush' );
83
- $w3_cacheflush->flush_post( $id );
84
- }
85
- catch ( \Exception $e ) {
86
- \WP_CLI::error( __( 'Flushing the page from cache failed.', 'w3-total-cache' ) );
87
- }
88
- \WP_CLI::success( __( 'The page is flushed from cache successfully.', 'w3-total-cache' ) );
89
- } else {
90
- \WP_CLI::error( __( 'There is no post with this permalink.', 'w3-total-cache' ) );
91
  }
 
 
 
 
92
  } else {
93
  if ( isset( $flushed_page_cache ) && $flushed_page_cache )
94
  break;
95
 
96
- $flushed_page_cache = true;
97
  try {
98
- $w3_cacheflush = Dispatcher::component( 'CacheFlush' );
99
- $w3_cacheflush->flush_posts();
100
  }
101
  catch ( \Exception $e ) {
102
  \WP_CLI::error( __( 'Flushing the page cache failed.', 'w3-total-cache' ) );
103
  }
104
  \WP_CLI::success( __( 'The page cache is flushed successfully.', 'w3-total-cache' ) );
105
  }
 
 
 
 
106
  }
107
  } while ( !empty( $args ) );
108
  }
109
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
 
111
  /**
112
- * Update query string function
113
  */
114
  function querystring() {
115
-
116
  try {
117
  $w3_querystring = Dispatcher::component( 'CacheFlush' );
118
  $w3_querystring->browsercache_flush();
@@ -128,9 +315,7 @@ class W3TotalCache_Command extends \WP_CLI_Command {
128
  }
129
 
130
  /**
131
- * Purge URL's from cdn and varnish if enabled
132
- *
133
- * @param array $args
134
  */
135
  function cdn_purge( $args = array() ) {
136
  $purgeitems = array();
@@ -196,7 +381,7 @@ class W3TotalCache_Command extends \WP_CLI_Command {
196
  }
197
 
198
  /**
199
- * Tell opcache to reload PHP files
200
  *
201
  * @param array $args
202
  */
@@ -239,7 +424,7 @@ class W3TotalCache_Command extends \WP_CLI_Command {
239
  }
240
 
241
  /**
242
- * triggers PgCache Garbage Cleanup
243
  */
244
  function pgcache_cleanup() {
245
  try {
@@ -253,62 +438,9 @@ class W3TotalCache_Command extends \WP_CLI_Command {
253
  \WP_CLI::success( __( 'PageCache Garbage cleanup triggered successfully.',
254
  'w3-total-cache' ) );
255
  }
 
256
 
257
- /**
258
- * triggers PgCache Garbage Cleanup
259
- */
260
- function fix_environment( $args = array(), $vars = array() ) {
261
- $server_type = array_shift( $args );
262
- switch ( $server_type ) {
263
- case 'apache':
264
- $_SERVER['SERVER_SOFTWARE'] = 'Apache';
265
- break;
266
- case 'nginx':
267
- $_SERVER['SERVER_SOFTWARE'] = 'nginx';
268
- break;
269
- }
270
-
271
- try {
272
- $config = Dispatcher::config();
273
- $environment = Dispatcher::component( 'Root_Environment' );
274
- $environment->fix_in_wpadmin( $config, true );
275
- } catch ( Util_Environment_Exceptions $e ) {
276
- \WP_CLI::error( __( 'Environment adjustment failed with error', 'w3-total-cache' ),
277
- $e->getCombinedMessage() );
278
- }
279
-
280
- \WP_CLI::success( __( 'Environment adjusted.', 'w3-total-cache' ) );
281
- }
282
 
283
- /**
284
- * Help function for this command
285
- */
286
- public static function help() {
287
- \WP_CLI::line( <<<EOB
288
- usage: wp w3-total-cache flush [post|database|minify|object] [--post_id=<post-id>] [--permalink=<post-permalink>]
289
- or : wp w3-total-cache querystring
290
- or : wp w3-total-cache cdn_purge <file> [<file2>]...
291
- or : wp w3-total-cache pgcache_cleanup
292
-
293
- flush flushes whole cache or specific items based on provided arguments
294
- querystring update query string for all static files
295
- cdn_purge Purges command line provided files from Varnish and the CDN
296
- pgcache_cleanup Generally triggered from a cronjob, allows for manual Garbage collection of page cache to be triggered
297
- opcache_flush_file SNS/local file.php Tells opcache to compile files
298
- opcache_flush SNS/local expression Tells opcache to delete all files
299
- fix_environment Creates missing files, writes apache/nginx rules. Subcommand defines server type:
300
- apache create rules for apache server
301
- nginx create rules for nginx server
302
- Available flush sub-commands:
303
- --post_id=<id> flush a specific post ID
304
- --permalink=<post-permalink> flush a specific permalink
305
- database flush the database cache
306
- object flush the object cache
307
- minify flush the minify cache
308
- EOB
309
- );
310
- }
311
- }
312
 
313
  if ( method_exists( '\WP_CLI', 'add_command' ) ) {
314
  \WP_CLI::add_command( 'w3-total-cache', '\W3TC\W3TotalCache_Command' );
2
  namespace W3TC;
3
 
4
  /**
5
+ * The W3 Total Cache plugin integration
6
  *
7
  * @package wp-cli
8
  * @subpackage commands/third-party
9
  */
10
  class W3TotalCache_Command extends \WP_CLI_Command {
11
+ /**
12
+ * Creates missing files, writes apache/nginx rules.
13
+ *
14
+ * ## OPTIONS
15
+ * [<server>]
16
+ * : Subcommand defines server type:
17
+ * apache create rules for apache server
18
+ * nginx create rules for nginx server
19
+ */
20
+ function fix_environment( $args = array(), $vars = array() ) {
21
+ $server_type = array_shift( $args );
22
+ switch ( $server_type ) {
23
+ case 'apache':
24
+ $_SERVER['SERVER_SOFTWARE'] = 'Apache';
25
+ break;
26
+ case 'nginx':
27
+ $_SERVER['SERVER_SOFTWARE'] = 'nginx';
28
+ break;
29
+ }
30
+
31
+ try {
32
+ $config = Dispatcher::config();
33
+ $environment = Dispatcher::component( 'Root_Environment' );
34
+ $environment->fix_in_wpadmin( $config, true );
35
+ } catch ( Util_Environment_Exceptions $e ) {
36
+ \WP_CLI::error( __( 'Environment adjustment failed with error', 'w3-total-cache' ),
37
+ $e->getCombinedMessage() );
38
+ }
39
+
40
+ \WP_CLI::success( __( 'Environment adjusted.', 'w3-total-cache' ) );
41
+ }
42
+
43
+
44
 
45
  /**
46
+ * Clear something from the cache.
47
  *
48
+ * ## OPTIONS
49
+ * <cache>
50
+ * : Cache to flush
51
+ * all flush all caches
52
+ * posts flush posts (pagecache and further)
53
+ * post flush the page cache
54
+ * database flush the database cache
55
+ * object flush the object cache
56
+ * minify flush the minify cache
57
+ *
58
+ * [--post_id=<id>]
59
+ * : flush a specific post ID
60
+ *
61
+ * [--permalink=<post-permalink>]
62
+ * : flush a specific permalink
63
+ *
64
+ * ## EXAMPLES
65
+ * # Flush all
66
+ * $ wp w3-total-cache flush all
67
+ *
68
+ * # Flush pagecache and reverse proxies
69
+ * $ wp w3-total-cache flush posts
70
  */
71
  function flush( $args = array(), $vars = array() ) {
72
  $args = array_unique( $args );
75
  $cache_type = array_shift( $args );
76
 
77
  switch ( $cache_type ) {
78
+ case 'all':
79
+ try {
80
+ w3tc_flush_all();
81
+ }
82
+ catch ( \Exception $e ) {
83
+ \WP_CLI::error( __( 'Flushing all failed.', 'w3-total-cache' ) );
84
+ }
85
+ \WP_CLI::success( __( 'Everything flushed successfully.', 'w3-total-cache' ) );
86
+ break;
87
+
88
+ case 'posts':
89
+ try {
90
+ w3tc_flush_posts();
91
+ }
92
+ catch ( \Exception $e ) {
93
+ \WP_CLI::error( __( 'Flushing posts/pages failed.', 'w3-total-cache' ) );
94
+ }
95
+ \WP_CLI::success( __( 'Posts/pages flushed successfully.', 'w3-total-cache' ) );
96
+ break;
97
+
98
  case 'db':
99
  case 'database':
100
  try {
130
  break;
131
 
132
  case 'post':
 
133
  if ( isset( $vars['post_id'] ) ) {
134
  if ( is_numeric( $vars['post_id'] ) ) {
135
  try {
136
+ w3tc_flush_post( $vars['post_id'] );
 
137
  }
138
  catch ( \Exception $e ) {
139
  \WP_CLI::error( __( 'Flushing the page from cache failed.', 'w3-total-cache' ) );
142
  } else {
143
  \WP_CLI::error( __( 'This is not a valid post id.', 'w3-total-cache' ) );
144
  }
 
 
145
  }
146
  elseif ( isset( $vars['permalink'] ) ) {
147
+ try {
148
+ w3tc_flush_url( $vars['permalink'] );
 
 
 
 
 
 
 
 
 
 
 
149
  }
150
+ catch ( \Exception $e ) {
151
+ \WP_CLI::error( __( 'Flushing the page from cache failed.', 'w3-total-cache' ) );
152
+ }
153
+ \WP_CLI::success( __( 'The page is flushed from cache successfully.', 'w3-total-cache' ) );
154
  } else {
155
  if ( isset( $flushed_page_cache ) && $flushed_page_cache )
156
  break;
157
 
 
158
  try {
159
+ w3tc_flush_posts();
 
160
  }
161
  catch ( \Exception $e ) {
162
  \WP_CLI::error( __( 'Flushing the page cache failed.', 'w3-total-cache' ) );
163
  }
164
  \WP_CLI::success( __( 'The page cache is flushed successfully.', 'w3-total-cache' ) );
165
  }
166
+ break;
167
+
168
+ default:
169
+ \WP_CLI::error( __( 'Not specified what to flush', 'w3-total-cache' ) );
170
  }
171
  } while ( !empty( $args ) );
172
  }
173
 
174
+ /**
175
+ * Get or set option.
176
+ *
177
+ * Options modifications don't update your .htaccess automatically.
178
+ * Use fix_environment command afterwards to do it.
179
+ *
180
+ * ## OPTIONS
181
+ * <operation>
182
+ * : operation to do
183
+ * get get option value
184
+ * set set option value
185
+ * <name>
186
+ * : option name
187
+ *
188
+ * [<value>]
189
+ * : (for set operation) Value to set
190
+ *
191
+ * [--state]
192
+ * : use state, not config
193
+ * state is used for backend notifications
194
+ *
195
+ * [--master]
196
+ * : use master config/state
197
+ *
198
+ * [--type=<type>]
199
+ * : type of data used boolean/string/integer/array. Default string
200
+ *
201
+ * [--delimiter=<delimiter>]
202
+ * : delimiter to use for array type values
203
+ *
204
+ * ## EXAMPLES
205
+ * # get if pagecache enabled
206
+ * $ wp w3-total-cache option get pgcache.enabled --type=boolean
207
+ *
208
+ * # enable pagecache
209
+ * $ wp w3-total-cache option set pgcache.enabled true --type=boolean
210
+ *
211
+ * # don't show wp-content permissions notification
212
+ * $ wp w3-total-cache option set common.hide_note_wp_content_permissions true --state --type=boolean
213
+ */
214
+ function option( $args = array(), $vars = array() ) {
215
+ $op = array_shift( $args );
216
+ $name = array_shift( $args );
217
+
218
+ if ( empty( $name ) ) {
219
+ \WP_CLI::error( __( '<name> parameter is not specified', 'w3-total-cache' ) );
220
+ return;
221
+ }
222
+ if ( strpos( $name, '::' ) !== FALSE ) {
223
+ $name = explode('::', $name);
224
+ }
225
+
226
+ $c = null;
227
+ if ( isset( $vars['state'] ) ) {
228
+ if ( isset( $vars['master'] ) )
229
+ $c = Dispatcher::config_state_master();
230
+ else
231
+ $c = Dispatcher::config_state();
232
+ } else {
233
+ if ( isset( $vars['master'] ) )
234
+ $c = Dispatcher::config_master();
235
+ else
236
+ $c = Dispatcher::config();
237
+ }
238
+
239
+ if ( $op == 'get') {
240
+ $type =( isset( $vars['type'] ) ? $vars['type'] : 'string' );
241
+
242
+ if ( $type == 'boolean' )
243
+ $v = $c->get_boolean( $name ) ? 'true' : 'false';
244
+ elseif ( $type == 'integer' )
245
+ $v = $c->get_integer( $name );
246
+ elseif ( $type == 'string' )
247
+ $v = $c->get_string( $name );
248
+ elseif ( $type == 'array' )
249
+ $v = json_encode( $c->get_array( $name ), JSON_PRETTY_PRINT );
250
+ else {
251
+ \WP_CLI::error( __( 'Unknown type ' . $type, 'w3-total-cache' ) );
252
+ return;
253
+ }
254
+
255
+ echo $v . "\n";
256
+ } elseif ( $op == 'set' ) {
257
+ $type =( isset( $vars['type'] ) ? $vars['type'] : 'string' );
258
+
259
+ if ( count( $args ) <= 0 ) {
260
+ \WP_CLI::error( __( '<value> parameter is not specified', 'w3-total-cache' ) );
261
+ return;
262
+ }
263
+ $value = array_shift( $args );
264
+
265
+ if ( $type == 'boolean' ) {
266
+ if ( $value == 'true' || $value == '1' || $value == 'on' )
267
+ $v = true;
268
+ elseif ( $value == 'false' || $value == '0' || $value == 'off' )
269
+ $v = false;
270
+ else {
271
+ \WP_CLI::error( __( '<value> parameter ' . $value . ' is not boolean', 'w3-total-cache' ) );
272
+ return;
273
+ }
274
+ } elseif ( $type == 'integer' )
275
+ $v = (integer)$value;
276
+ elseif ( $type == 'string' )
277
+ $v = $value;
278
+ elseif ( $type == 'array' ) {
279
+ $delimiter =( isset( $vars['delimiter'] ) ? $vars['delimiter'] : ',' );
280
+ $v = explode($delimiter, $value );
281
+ } else {
282
+ \WP_CLI::error( __( 'Unknown type ' . $type, 'w3-total-cache' ) );
283
+ return;
284
+ }
285
+
286
+ try {
287
+ $c->set( $name, $v );
288
+ $c->save();
289
+ \WP_CLI::success( __( 'Option updated successfully.', 'w3-total-cache' ) );
290
+ } catch ( \Exception $e ) {
291
+ \WP_CLI::error( __( 'Option value update failed.', 'w3-total-cache' ) );
292
+ }
293
+
294
+ } else {
295
+ \WP_CLI::error( __( '<operation> parameter is not specified', 'w3-total-cache' ) );
296
+ }
297
+ }
298
 
299
  /**
300
+ * Update query string for all static files
301
  */
302
  function querystring() {
 
303
  try {
304
  $w3_querystring = Dispatcher::component( 'CacheFlush' );
305
  $w3_querystring->browsercache_flush();
315
  }
316
 
317
  /**
318
+ * Purges URL's from cdn and varnish if enabled
 
 
319
  */
320
  function cdn_purge( $args = array() ) {
321
  $purgeitems = array();
381
  }
382
 
383
  /**
384
+ * SNS/local file.php Tells opcache to compile files
385
  *
386
  * @param array $args
387
  */
424
  }
425
 
426
  /**
427
+ * Generally triggered from a cronjob, allows for manual Garbage collection of page cache to be triggered
428
  */
429
  function pgcache_cleanup() {
430
  try {
438
  \WP_CLI::success( __( 'PageCache Garbage cleanup triggered successfully.',
439
  'w3-total-cache' ) );
440
  }
441
+ }
442
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
443
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
444
 
445
  if ( method_exists( '\WP_CLI', 'add_command' ) ) {
446
  \WP_CLI::add_command( 'w3-total-cache', '\W3TC\W3TotalCache_Command' );
Config.php CHANGED
@@ -21,6 +21,7 @@ class Config {
21
 
22
  private $_md5;
23
  private $_data;
 
24
 
25
 
26
 
@@ -34,7 +35,7 @@ class Config {
34
  // problems with APC, ZendCache, and WSOD in a case of
35
  // broken config file
36
  $content = @file_get_contents( $filename );
37
- $config = @json_decode( $content, true );
38
 
39
  if ( is_array( $config ) )
40
  return $config;
@@ -50,7 +51,7 @@ class Config {
50
  * Stored in this class to limit class loading
51
  */
52
  static public function util_config_filename( $blog_id, $preview ) {
53
- $postfix = ( $preview ? '-preview' : '' ) . '.json';
54
 
55
  if ( $blog_id <= 0 )
56
  return W3TC_CONFIG_DIR . '/master' . $postfix;
@@ -65,7 +66,7 @@ class Config {
65
  * Stored in this class to limit class loading
66
  * v<0.9.5
67
  */
68
- static public function util_config_filename_legacy( $blog_id, $preview ) {
69
  $postfix = ( $preview ? '-preview' : '' ) . '.php';
70
 
71
  if ( $blog_id <= 0 )
@@ -74,6 +75,20 @@ class Config {
74
  return W3TC_CONFIG_DIR . '/' . sprintf( '%06d', $blog_id ) . $postfix;
75
  }
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
 
79
  public function __construct( $blog_id = null ) {
@@ -248,6 +263,10 @@ class Config {
248
  return $this->_is_master;
249
  }
250
 
 
 
 
 
251
 
252
 
253
  /**
@@ -358,6 +377,7 @@ class Config {
358
  }
359
 
360
  $this->_data = $data;
 
361
  }
362
 
363
 
@@ -369,5 +389,6 @@ class Config {
369
  $c = new ConfigCompiler( $this->_blog_id, $this->_preview );
370
  $c->load();
371
  $this->_data = $c->get_data();
 
372
  }
373
  }
21
 
22
  private $_md5;
23
  private $_data;
24
+ private $_compiled;
25
 
26
 
27
 
35
  // problems with APC, ZendCache, and WSOD in a case of
36
  // broken config file
37
  $content = @file_get_contents( $filename );
38
+ $config = @json_decode( substr( $content, 14 ), true );
39
 
40
  if ( is_array( $config ) )
41
  return $config;
51
  * Stored in this class to limit class loading
52
  */
53
  static public function util_config_filename( $blog_id, $preview ) {
54
+ $postfix = ( $preview ? '-preview' : '' ) . '.php';
55
 
56
  if ( $blog_id <= 0 )
57
  return W3TC_CONFIG_DIR . '/master' . $postfix;
66
  * Stored in this class to limit class loading
67
  * v<0.9.5
68
  */
69
+ static public function util_config_filename_legacy_v1( $blog_id, $preview ) {
70
  $postfix = ( $preview ? '-preview' : '' ) . '.php';
71
 
72
  if ( $blog_id <= 0 )
75
  return W3TC_CONFIG_DIR . '/' . sprintf( '%06d', $blog_id ) . $postfix;
76
  }
77
 
78
+ /*
79
+ * Returns config filename
80
+ * Stored in this class to limit class loading
81
+ * v = 0.9.5 - 0.9.5.1
82
+ */
83
+ static public function util_config_filename_legacy_v2( $blog_id, $preview ) {
84
+ $postfix = ( $preview ? '-preview' : '' ) . '.json';
85
+
86
+ if ( $blog_id <= 0 )
87
+ return W3TC_CONFIG_DIR . '/master' . $postfix;
88
+ else
89
+ return W3TC_CONFIG_DIR . '/' . sprintf( '%06d', $blog_id ) . $postfix;
90
+ }
91
+
92
 
93
 
94
  public function __construct( $blog_id = null ) {
263
  return $this->_is_master;
264
  }
265
 
266
+ public function is_compiled() {
267
+ return $this->_compiled;
268
+ }
269
+
270
 
271
 
272
  /**
377
  }
378
 
379
  $this->_data = $data;
380
+ $this->_compiled = false;
381
  }
382
 
383
 
389
  $c = new ConfigCompiler( $this->_blog_id, $this->_preview );
390
  $c->load();
391
  $this->_data = $c->get_data();
392
+ $this->_compiled = true;
393
  }
394
  }
ConfigCompiler.php CHANGED
@@ -74,7 +74,7 @@ class ConfigCompiler {
74
  * Reads config from file and returns it's content as array (or null)
75
  * Stored in this class to limit class loading
76
  */
77
- static private function util_array_from_file_legacy( $filename ) {
78
  if ( file_exists( $filename ) && is_readable( $filename ) ) {
79
  // including file directly instead of read+eval causes constant
80
  // problems with APC, ZendCache, and WSOD in a case of
@@ -91,6 +91,27 @@ class ConfigCompiler {
91
 
92
 
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  public function __construct( $blog_id, $preview ) {
95
  $this->_blog_id = $blog_id;
96
  $this->_preview = $preview;
@@ -117,11 +138,18 @@ class ConfigCompiler {
117
  $data = Config::util_array_from_file( $master_filename );
118
  }
119
 
120
- // try to get legacy data
121
  if ( is_null( $data ) ) {
122
- $master_filename = Config::util_config_filename_legacy( 0,
123
  $this->_preview );
124
- $data = self::util_array_from_file_legacy( $master_filename );
 
 
 
 
 
 
 
125
  }
126
 
127
  if ( is_array( $data ) ) {
@@ -145,11 +173,18 @@ class ConfigCompiler {
145
  $data = Config::util_array_from_file( $child_filename );
146
  }
147
 
148
- // try to get legacy data
 
 
 
 
 
 
 
149
  if ( is_null( $data ) ) {
150
- $child_filename = Config::util_config_filename_legacy(
151
  $this->_blog_id, $this->_preview );
152
- $data = self::util_array_from_file_legacy( $child_filename );
153
  }
154
 
155
  if ( is_array( $data ) ) {
@@ -203,7 +238,7 @@ class ConfigCompiler {
203
  else // for older php versions
204
  $config = json_encode( $data );
205
 
206
- Util_File::file_put_contents_atomic( $filename, $config );
207
  }
208
 
209
 
74
  * Reads config from file and returns it's content as array (or null)
75
  * Stored in this class to limit class loading
76
  */
77
+ static private function util_array_from_file_legacy_v1( $filename ) {
78
  if ( file_exists( $filename ) && is_readable( $filename ) ) {
79
  // including file directly instead of read+eval causes constant
80
  // problems with APC, ZendCache, and WSOD in a case of
91
 
92
 
93
 
94
+ /**
95
+ * Reads config from file and returns it's content as array (or null)
96
+ * Stored in this class to limit class loading
97
+ */
98
+ static private function util_array_from_file_legacy_v2( $filename ) {
99
+ if ( file_exists( $filename ) && is_readable( $filename ) ) {
100
+ // including file directly instead of read+eval causes constant
101
+ // problems with APC, ZendCache, and WSOD in a case of
102
+ // broken config file
103
+ $content = @file_get_contents( $filename );
104
+ $config = @json_decode( $content, true );
105
+
106
+ if ( is_array( $config ) )
107
+ return $config;
108
+ }
109
+
110
+ return null;
111
+ }
112
+
113
+
114
+
115
  public function __construct( $blog_id, $preview ) {
116
  $this->_blog_id = $blog_id;
117
  $this->_preview = $preview;
138
  $data = Config::util_array_from_file( $master_filename );
139
  }
140
 
141
+ // try to get legacy v2 data
142
  if ( is_null( $data ) ) {
143
+ $master_filename = Config::util_config_filename_legacy_v2( 0,
144
  $this->_preview );
145
+ $data = self::util_array_from_file_legacy_v2( $master_filename );
146
+ }
147
+
148
+ // try to get legacy v1 data
149
+ if ( is_null( $data ) ) {
150
+ $master_filename = Config::util_config_filename_legacy_v1( 0,
151
+ $this->_preview );
152
+ $data = self::util_array_from_file_legacy_v1( $master_filename );
153
  }
154
 
155
  if ( is_array( $data ) ) {
173
  $data = Config::util_array_from_file( $child_filename );
174
  }
175
 
176
+ // try to get legacy v2 data
177
+ if ( is_null( $data ) ) {
178
+ $child_filename = Config::util_config_filename_legacy_v2(
179
+ $this->_blog_id, $this->_preview );
180
+ $data = self::util_array_from_file_legacy_v2( $child_filename );
181
+ }
182
+
183
+ // try to get legacy v1 data
184
  if ( is_null( $data ) ) {
185
+ $child_filename = Config::util_config_filename_legacy_v1(
186
  $this->_blog_id, $this->_preview );
187
+ $data = self::util_array_from_file_legacy_v1( $child_filename );
188
  }
189
 
190
  if ( is_array( $data ) ) {
238
  else // for older php versions
239
  $config = json_encode( $data );
240
 
241
+ Util_File::file_put_contents_atomic( $filename, '<?php exit; ?>' . $config );
242
  }
243
 
244
 
ConfigKeys.php CHANGED
@@ -160,6 +160,14 @@ $keys = array(
160
  'type' => 'boolean',
161
  'default' => false
162
  ),
 
 
 
 
 
 
 
 
163
  'objectcache.engine' => array(
164
  'type' => 'string',
165
  'default' => 'file'
@@ -351,7 +359,8 @@ $keys = array(
351
  'Last-Modified',
352
  'Content-Type',
353
  'X-Pingback',
354
- 'P3P'
 
355
  )
356
  ),
357
  'pgca