W3 Total Cache - Version 0.9.6

Version Description

  • Fixed anonymous usage tracking, default to disabled
  • Fixed incorrect minify cache data written if target directory missing
  • Fixed empty minify cache file written when file locking enabled
  • Fixed missing commas in CSS (@nigrosimone)
  • Fixed typo in object cache engine (@Furniel)
  • Fixed incorrect reuse of redis connections when persistent connections option enabled
  • Fixed reliability of Google Drive (via jikamens)
  • Fixed handling of UTF-8 encoded files by writing them in binary (via jikamens)
  • Improved Full Site Delivery configuration user flow on the General and CDN settings screens
  • Improved content type matching and cache hits as a result
  • Improved minify file locking logic
  • Improved visual langage of the compatibility test (@Furniel)
  • Improved configuration file management
  • Improved MaxCDN set up wizard
  • Improved page cache's accepted query string handling to handle optional values and add support for disk enhanced mode (via amiga-500, nigrosimone)
  • Improved handling of timeouts to origin push CDN proviers
  • Added HTTP/2 push headers for disk enhanced page caching (via nigrosimone)
  • Added X-Forwarded-Proto header for use cases like HTTPS recognition behind proxies or load balancers
  • Added multiple CDN support i.e. static file objects and pages, posts, feeds, API responses etc to use different respective CDN providers
  • Added page caching by cookie name or value (sponsored by SQweb)
  • Added toggle for CORS header to improve inter-operatbility with various CDN providers
  • Added support for CDN hosted media to media library (inspired by amiga-500)
  • Added object caching of AJAX calls (via andyexeter)
  • Enterprise features are now available to Pro subscribers! Including reading from multiple databases concurrently and purging caches across multiple hosts via a Message Bus
Download this release

Release Info

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

Code changes from version 0.9.5.4 to 0.9.6

Files changed (221) hide show
  1. BrowserCache_Environment.php +17 -15
  2. Cache.php +0 -4
  3. CacheFlush.php +4 -4
  4. CacheFlush_Locally.php +15 -7
  5. Cache_File_Generic.php +40 -19
  6. Cache_Memcache.php +8 -0
  7. Cache_Memcached.php +8 -0
  8. Cache_Redis.php +12 -2
  9. CdnEngine.php +0 -4
  10. CdnEngine_Azure.php +8 -3
  11. CdnEngine_Base.php +13 -1
  12. CdnEngine_Ftp.php +7 -3
  13. CdnEngine_GoogleDrive.php +146 -47
  14. CdnEngine_Mirror_Akamai.php +0 -4
  15. CdnEngine_Mirror_Cotendo.php +0 -4
  16. CdnEngine_Mirror_Edgecast.php +0 -4
  17. CdnEngine_Mirror_MaxCdn.php +168 -4
  18. CdnEngine_Mirror_Netdna.php +0 -178
  19. CdnEngine_RackSpaceCloudFiles.php +7 -3
  20. CdnEngine_S3.php +40 -11
  21. CdnEngine_S3_Cf.php +16 -3
  22. CdnEngine_S3_Compatible.php +9 -3
  23. Cdn_AdminActions.php +20 -337
  24. Cdn_AdminNotes.php +1 -21
  25. Cdn_CloudFrontFsd_Page.php +0 -18
  26. Cdn_ConfigLabels.php +2 -0
  27. Cdn_Core.php +21 -10
  28. Cdn_Core_Admin.php +7 -7
  29. Cdn_Environment.php +66 -32
  30. Cdn_Fsd_Core.php +0 -41
  31. Cdn_GeneralPage_View.php +3 -1
  32. Cdn_Highwinds_Page_View.js +1 -1
  33. Cdn_Highwinds_Page_View.php +3 -3
  34. Cdn_Highwinds_Popup_View_ConfigureCnamesForm.php +1 -1
  35. Cdn_MaxCdnFsd_Page.php +0 -18
  36. Cdn_MaxCdn_Page.php +28 -0
  37. Cdn_MaxCdn_Page_View.js +68 -0
  38. Cdn_MaxCdn_Page_View.php +96 -0
  39. Cdn_MaxCdn_Popup.php +282 -0
  40. Cdn_MaxCdn_Popup_View_Intro.php +39 -0
  41. Cdn_MaxCdn_Popup_View_Success.php +23 -0
  42. Cdn_MaxCdn_Popup_View_Zone.php +74 -0
  43. Cdn_MaxCdn_Popup_View_Zones.php +53 -0
  44. Cdn_Page.php +0 -32
  45. Cdn_Page_View_Fsd_HeaderActions.php +1 -1
  46. Cdn_Plugin.php +67 -31
  47. Cdn_Plugin_Admin.php +55 -56
  48. Cdn_Plugin_WidgetMaxCdn.php +0 -9
  49. Cdn_Plugin_WidgetNetDna.php +0 -191
  50. Cdn_RackSpaceCdn_Page_View.js +1 -1
  51. Cdn_RackSpaceCdn_Page_View.php +3 -3
  52. Cdn_RackSpaceCdn_Popup_View_ConfigureDomains.php +1 -1
  53. Cdn_RackSpaceCloudFiles_Page_View.php +3 -3
  54. Cdn_Util.php +2 -23
  55. Cdn_Fsd_CacheFlush.php → Cdnfsd_CacheFlush.php +17 -11
  56. Cdn_CloudFrontFsd_Api.php → Cdnfsd_CloudFront_Api.php +1 -1
  57. Cdn_CloudFrontFsd_Engine.php → Cdnfsd_CloudFront_Engine.php +3 -3
  58. Cdnfsd_CloudFront_Page.php +18 -0
  59. Cdn_CloudFrontFsd_Page_View.js → Cdnfsd_CloudFront_Page_View.js +1 -1
  60. Cdn_CloudFrontFsd_Page_View.php → Cdnfsd_CloudFront_Page_View.php +5 -13
  61. Cdn_CloudFrontFsd_Popup.php → Cdnfsd_CloudFront_Popup.php +19 -19
  62. Cdn_CloudFrontFsd_Popup_View_Distribution.php → Cdnfsd_CloudFront_Popup_View_Distribution.php +0 -0
  63. Cdn_CloudFrontFsd_Popup_View_Distributions.php → Cdnfsd_CloudFront_Popup_View_Distributions.php +0 -0
  64. Cdn_CloudFrontFsd_Popup_View_Intro.php → Cdnfsd_CloudFront_Popup_View_Intro.php +2 -2
  65. Cdn_CloudFrontFsd_Popup_View_Success.php → Cdnfsd_CloudFront_Popup_View_Success.php +0 -0
  66. Cdnfsd_Core.php +54 -0
  67. Cdnfsd_GeneralPage_View.php +37 -0
  68. Cdnfsd_Limelight_Api.php +101 -0
  69. Cdnfsd_Limelight_Engine.php +85 -0
  70. Cdnfsd_Limelight_Page.php +18 -0
  71. Cdnfsd_Limelight_Page_View.js +42 -0
  72. Cdnfsd_Limelight_Page_View.php +43 -0
  73. Cdnfsd_Limelight_Popup.php +68 -0
  74. Cdnfsd_Limelight_Popup_View_Intro.php +49 -0
  75. Cdnfsd_Limelight_Popup_View_Success.php +22 -0
  76. Cdn_MaxCdnFsd_Engine.php → Cdnfsd_MaxCdn_Engine.php +1 -1
  77. Cdnfsd_MaxCdn_Page.php +20 -0
  78. Cdn_MaxCdnFsd_Page_View.js → Cdnfsd_MaxCdn_Page_View.js +17 -1
  79. Cdn_MaxCdnFsd_Page_View.php → Cdnfsd_MaxCdn_Page_View.php +5 -16
  80. Cdn_MaxCdnFsd_Popup.php → Cdnfsd_MaxCdn_Popup.php +53 -15
  81. Cdn_MaxCdnFsd_Popup_View_Intro.php → Cdnfsd_MaxCdn_Popup_View_Intro.php +0 -0
  82. Cdn_MaxCdnFsd_Popup_View_Success.php → Cdnfsd_MaxCdn_Popup_View_Success.php +0 -0
  83. Cdn_MaxCdnFsd_Popup_View_Zone.php → Cdnfsd_MaxCdn_Popup_View_Zone.php +6 -2
  84. Cdn_MaxCdnFsd_Popup_View_Zones.php → Cdnfsd_MaxCdn_Popup_View_Zones.php +0 -0
  85. Cdnfsd_Page_View_Header.php +15 -0
  86. Cdnfsd_Plugin.php +61 -0
  87. Cdnfsd_Plugin_Admin.php +91 -0
  88. Cdn_Fsd_Util.php → Cdnfsd_Util.php +9 -1
  89. Cli.php +26 -0
  90. Config.php +49 -24
  91. ConfigCache.php +108 -0
  92. ConfigCompiler.php +56 -52
  93. ConfigDbStorage.php +390 -0
  94. ConfigKeys.php +91 -41
  95. ConfigState.php +0 -2
  96. ConfigUtil.php +81 -0
  97. DbCache_Environment.php +7 -1
  98. DbCache_Wpdb.php +42 -2
  99. DbCache_WpdbInjection.php +8 -0
  100. DbCache_WpdbInjection_QueryCaching.php +23 -17
  101. Dispatcher.php +1 -14
  102. Enterprise_CacheFlush_MakeSnsEvent.php +10 -4
  103. Enterprise_Dbcache_WpdbInjection_Cluster.php +116 -43
  104. Extension_Amp_Plugin.php +3 -7
  105. Extension_CloudFlare_Api.php +1 -1
  106. Extension_CloudFlare_Cdn_Page_View.php +31 -0
  107. Extension_CloudFlare_Page.php +10 -2
  108. Extension_CloudFlare_Plugin_Admin.php +58 -6
  109. Extension_CloudFlare_Popup_View_Zones.php +41 -39
  110. Extension_CloudFlare_SettingsForUi.php +2 -2
  111. Extension_FragmentCache_Plugin_Admin.php +7 -8
  112. Extension_FragmentCache_WpObjectCache.php +12 -15
  113. Extension_NewRelic_Plugin.php +30 -13
  114. Extension_NewRelic_Plugin_Admin.php +6 -7
  115. Extension_NewRelic_Popup_View.js +8 -8
  116. Extension_Swarmify_Page.php +1 -8
  117. Extension_WordPressSeo_Plugin_Admin.php +0 -12
  118. Extensions_Plugin_Admin.php +7 -7
  119. Generic_AdminActions_Config.php +6 -36
  120. Generic_AdminActions_Default.php +9 -6
  121. Generic_AdminActions_EdgeMode.php +0 -28
  122. Generic_AdminActions_Flush.php +1 -1
  123. Generic_AdminActions_Test.php +8 -2
  124. Generic_ConfigLabels.php +1 -0
  125. Generic_Environment.php +8 -27
  126. Generic_Faq.php +0 -2
  127. Generic_GeneralPage_View_ShowEdge.js +3 -3
  128. Generic_GeneralPage_View_ShowSupportUs.js +6 -3
  129. Generic_Page_Dashboard_View.css +33 -20
  130. Generic_Page_General.php +0 -1
  131. Generic_Plugin.php +19 -18
  132. Generic_Plugin_Admin.php +13 -4
  133. Generic_Plugin_AdminCompatibility.php +0 -27
  134. Generic_Plugin_AdminNotifications.php +0 -29
  135. Minify_ContentMinifier.php +1 -1
  136. Minify_Plugin.php +25 -23
  137. Minify_Plugin_Admin.php +1 -3
  138. ModuleStatus.php +0 -16
  139. ObjectCache_Environment.php +7 -1
  140. ObjectCache_WpObjectCache_Regular.php +43 -36
  141. PageSpeed_Api.php +13 -5
  142. PageSpeed_Plugin_Widget.php +4 -2
  143. PgCache_ConfigLabels.php +4 -0
  144. PgCache_ContentGrabber.php +302 -134
  145. PgCache_Environment.php +166 -16
  146. PgCache_Flush.php +14 -8
  147. PgCache_Page.php +1 -3
  148. PgCache_Page_CookieGroups.php +78 -0
  149. PgCache_Page_CookieGroups_View.js +96 -0
  150. PgCache_Page_CookieGroups_View.php +113 -0
  151. PgCache_Plugin_Admin.php +43 -0
  152. Root_AdminActions.php +0 -1
  153. Root_AdminActivation.php +1 -1
  154. Root_AdminMenu.php +51 -36
  155. Root_Loader.php +10 -8
  156. Support_AdminActions.php +0 -2
  157. Util_Admin.php +3 -25
  158. Util_AttachToActions.php +12 -0
  159. Util_Debug.php +9 -0
  160. Util_Environment.php +26 -34
  161. Util_PageUrls.php +3 -1
  162. Util_Rule.php +9 -3
  163. Util_RuleSnippet.php +10 -33
  164. Util_Ui.php +1 -1
  165. inc/lightbox/edge.php +0 -24
  166. inc/lightbox/self_test.php +61 -60
  167. inc/lightbox/support_us.php +5 -1
  168. inc/lightbox/upgrade.php +2 -2
  169. inc/options/about.php +1 -1
  170. inc/options/cdn.php +17 -1
  171. inc/options/cdn/akamai.php +1 -1
  172. inc/options/cdn/att.php +2 -2
  173. inc/options/cdn/azure.php +1 -1
  174. inc/options/cdn/cf.php +24 -7
  175. inc/options/cdn/cf2.php +1 -1
  176. inc/options/cdn/common/cnames.php +13 -4
  177. inc/options/cdn/cotendo.php +2 -2
  178. inc/options/cdn/edgecast.php +2 -2
  179. inc/options/cdn/ftp.php +1 -1
  180. inc/options/cdn/maxcdn.php +0 -89
  181. inc/options/cdn/mirror.php +2 -2
  182. inc/options/cdn/netdna.php +0 -89
  183. inc/options/cdn/rscf.php +1 -1
  184. inc/options/cdn/s3.php +24 -6
  185. inc/options/cdn/s3_compatible.php +1 -1
  186. inc/options/common/header.php +1 -1
  187. inc/options/dashboard.php +2 -2
  188. inc/options/general.php +11 -32
  189. inc/options/minify.php +2 -2
  190. inc/options/minify/yuijs2.php +6 -6
  191. inc/options/pgcache.php +42 -6
  192. inc/popup/cdn_purge.php +1 -1
  193. inc/widget/maxcdn_signup.php +1 -30
  194. inc/widget/netdna.php +0 -64
  195. inc/widget/netdna_signup.php +0 -53
  196. ini/config-db-sample.php +34 -0
  197. ini/dbcluster-config-sample.php +175 -149
  198. ini/web.config +28 -3
  199. languages/faq-en_US.xml +6 -1
  200. languages/faq-pro-en_US.xml +4 -4
  201. languages/w3-total-cache.pot +1 -26
  202. lib/Minify/CSSmin.php +0 -758
  203. lib/Minify/Minify/CSS/UriRewriter.php +1 -2
  204. lib/Minify/Minify/Cache/File.php +3 -2
  205. lib/Minify/Minify/ClosureCompiler.php +8 -1
  206. lib/Minify/Minify/HTML.php +1 -1
  207. lib/Minify/Minify/YUICompressor.php +30 -24
  208. lib/Minify/YUI-CSS-compressor-PHP-port-4.1.0/Colors.php +155 -0
  209. lib/Minify/YUI-CSS-compressor-PHP-port-4.1.0/Command.php +223 -0
  210. lib/Minify/YUI-CSS-compressor-PHP-port-4.1.0/Minifier.php +862 -0
  211. lib/Minify/YUI-CSS-compressor-PHP-port-4.1.0/Utils.php +149 -0
  212. lib/NetDNA/NetDNA.php +424 -407
  213. lib/S3.php +1927 -429
  214. pub/css/lightbox.css +9 -0
  215. pub/css/options.css +185 -178
  216. pub/js/lightbox.js +3 -91
  217. pub/js/options.js +17 -280
  218. pub/opcache.php +1 -1
  219. readme.txt +29 -2
  220. w3-total-cache-api.php +20 -15
  221. w3-total-cache.php +1 -1
BrowserCache_Environment.php CHANGED
@@ -316,7 +316,7 @@ class BrowserCache_Environment {
316
  $rules .= " BrowserMatch \\bMSI[E] !no-gzip !gzip-only-text/html\n";
317
  $rules .= " </IfModule>\n";
318
  }
319
- if ( version_compare( $this->_get_server_version(), '2.3.7', '>=' ) ) {
320
  $rules .= " <IfModule mod_filter.c>\n";
321
  }
322
  $rules .= " AddOutputFilterByType DEFLATE " . implode( ' ', $compression_types ) . "\n";
@@ -325,7 +325,7 @@ class BrowserCache_Environment {
325
  $rules .= " AddOutputFilter DEFLATE js css htm html xml\n";
326
  $rules .= " </IfModule>\n";
327
 
328
- if ( version_compare( $this->_get_server_version(), '2.3.7', '>=' ) ) {
329
  $rules .= " </IfModule>\n";
330
  }
331
  $rules .= "</IfModule>\n";
@@ -585,10 +585,12 @@ class BrowserCache_Environment {
585
  $mime_types, $section ) {
586
 
587
  $expires = $config->get_boolean( 'browsercache.' . $section . '.expires' );
 
588
  $cache_control = $config->get_boolean( 'browsercache.' . $section . '.cache.control' );
589
  $w3tc = $config->get_boolean( 'browsercache.' . $section . '.w3tc' );
 
590
 
591
- if ( $expires || $cache_control || $w3tc ) {
592
  $lifetime = $config->get_integer( 'browsercache.' . $section . '.lifetime' );
593
 
594
  $extensions = array_keys( $mime_types );
@@ -604,6 +606,18 @@ class BrowserCache_Environment {
604
  if ( $expires ) {
605
  $rules .= " expires " . $lifetime . "s;\n";
606
  }
 
 
 
 
 
 
 
 
 
 
 
 
607
 
608
  $add_header_rules = '';
609
 
@@ -794,18 +808,6 @@ class BrowserCache_Environment {
794
  return $rules;
795
  }
796
 
797
- /**
798
- * Returns the apache, nginx version
799
- *
800
- * @return string
801
- */
802
- private function _get_server_version() {
803
- $sig= explode( '/', $_SERVER['SERVER_SOFTWARE'] );
804
- $temp = isset( $sig[1] ) ? explode( ' ', $sig[1] ) : array( '0' );
805
- $version = $temp[0];
806
- return $version;
807
- }
808
-
809
  /**
810
  * Takes an array of extensions single per row and/or extensions delimited by |
811
  *
316
  $rules .= " BrowserMatch \\bMSI[E] !no-gzip !gzip-only-text/html\n";
317
  $rules .= " </IfModule>\n";
318
  }
319
+ if ( version_compare( Util_Environment::get_server_version(), '2.3.7', '>=' ) ) {
320
  $rules .= " <IfModule mod_filter.c>\n";
321
  }
322
  $rules .= " AddOutputFilterByType DEFLATE " . implode( ' ', $compression_types ) . "\n";
325
  $rules .= " AddOutputFilter DEFLATE js css htm html xml\n";
326
  $rules .= " </IfModule>\n";
327
 
328
+ if ( version_compare( Util_Environment::get_server_version(), '2.3.7', '>=' ) ) {
329
  $rules .= " </IfModule>\n";
330
  }
331
  $rules .= "</IfModule>\n";
585
  $mime_types, $section ) {
586
 
587
  $expires = $config->get_boolean( 'browsercache.' . $section . '.expires' );
588
+ $etag = $config->get_boolean( 'browsercache.' . $section . '.etag' );
589
  $cache_control = $config->get_boolean( 'browsercache.' . $section . '.cache.control' );
590
  $w3tc = $config->get_boolean( 'browsercache.' . $section . '.w3tc' );
591
+ $last_modified = $config->get_boolean( 'browsercache.' . $section . '.last_modified' );
592
 
593
+ if ( $etag || $expires || $cache_control || $w3tc || !$last_modified ) {
594
  $lifetime = $config->get_integer( 'browsercache.' . $section . '.lifetime' );
595
 
596
  $extensions = array_keys( $mime_types );
606
  if ( $expires ) {
607
  $rules .= " expires " . $lifetime . "s;\n";
608
  }
609
+ if ( version_compare( Util_Environment::get_server_version(), '1.3.3', '>=' ) ) {
610
+ if ( $etag ) {
611
+ $rules .= " etag on;\n";
612
+ } else {
613
+ $rules .= " etag off;\n";
614
+ }
615
+ }
616
+ if ( $last_modified ) {
617
+ $rules .= " if_modified_since exact;\n";
618
+ } else {
619
+ $rules .= " if_modified_since off;\n";
620
+ }
621
 
622
  $add_header_rules = '';
623
 
808
  return $rules;
809
  }
810
 
 
 
 
 
 
 
 
 
 
 
 
 
811
  /**
812
  * Takes an array of extensions single per row and/or extensions delimited by |
813
  *
Cache.php CHANGED
@@ -166,10 +166,6 @@ class Cache {
166
  $engine_name = 'mirror';
167
  break;
168
 
169
- case 'netdna':
170
- $engine_name = 'netdna';
171
- break;
172
-
173
  case 'maxcdn':
174
  $engine_name = 'maxcdn';
175
  break;
166
  $engine_name = 'mirror';
167
  break;
168
 
 
 
 
 
169
  case 'maxcdn':
170
  $engine_name = 'maxcdn';
171
  break;
CacheFlush.php CHANGED
@@ -128,8 +128,8 @@ class CacheFlush {
128
  /**
129
  * Purges/Flushes post page
130
  */
131
- function flush_post( $post_id ) {
132
- return $this->_executor->flush_post( $post_id );
133
  }
134
 
135
  /**
@@ -162,12 +162,12 @@ class CacheFlush {
162
  /**
163
  * Purges/Flushes url
164
  */
165
- function flush_url( $url ) {
166
  static $flushed_urls = array();
167
 
168
  if ( !in_array( $url, $flushed_urls ) ) {
169
  $flushed_urls[] = $url;
170
- return $this->_executor->flush_url( $url );
171
  }
172
  return true;
173
  }
128
  /**
129
  * Purges/Flushes post page
130
  */
131
+ function flush_post( $post_id, $extras = null ) {
132
+ return $this->_executor->flush_post( $post_id, $extras );
133
  }
134
 
135
  /**
162
  /**
163
  * Purges/Flushes url
164
  */
165
+ function flush_url( $url, $extras = null ) {
166
  static $flushed_urls = array();
167
 
168
  if ( !in_array( $url, $flushed_urls ) ) {
169
  $flushed_urls[] = $url;
170
+ return $this->_executor->flush_url( $url, $extras );
171
  }
172
  return true;
173
  }
CacheFlush_Locally.php CHANGED
@@ -83,7 +83,7 @@ class CacheFlush_Locally {
83
  function minifycache_flush_all( $extras = array() ) {
84
  if ( $extras['minify'] == 'purge_map' )
85
  delete_option( 'w3tc_minify' );
86
-
87
  $this->minifycache_flush( $extras );
88
  }
89
 
@@ -156,8 +156,10 @@ class CacheFlush_Locally {
156
  /**
157
  * Purges/Flushes post from page cache, varnish and cdn cache
158
  */
159
- function flush_post( $post_id ) {
160
- do_action( 'w3tc_flush_post', $post_id );
 
 
161
  }
162
 
163
  /**
@@ -165,7 +167,9 @@ class CacheFlush_Locally {
165
  * When global changes affect whole content but not internal data structures
166
  */
167
  function flush_posts( $extras = null ) {
168
- do_action( 'w3tc_flush_posts', $extras );
 
 
169
  }
170
 
171
  /**
@@ -198,14 +202,18 @@ class CacheFlush_Locally {
198
  $default_actions_added = true;
199
  }
200
 
201
- do_action( 'w3tc_flush_all', $extras );
 
 
202
  }
203
 
204
  /**
205
  * Purges/Flushes url from page cache, varnish and cdn cache
206
  */
207
- function flush_url( $url ) {
208
- do_action( 'w3tc_flush_url', $url );
 
 
209
  }
210
 
211
  /**
83
  function minifycache_flush_all( $extras = array() ) {
84
  if ( $extras['minify'] == 'purge_map' )
85
  delete_option( 'w3tc_minify' );
86
+
87
  $this->minifycache_flush( $extras );
88
  }
89
 
156
  /**
157
  * Purges/Flushes post from page cache, varnish and cdn cache
158
  */
159
+ function flush_post( $post_id, $extras = null ) {
160
+ $do_flush = apply_filters( 'w3tc_preflush_post', true, $extras );
161
+ if ( $do_flush )
162
+ do_action( 'w3tc_flush_post', $post_id );
163
  }
164
 
165
  /**
167
  * When global changes affect whole content but not internal data structures
168
  */
169
  function flush_posts( $extras = null ) {
170
+ $do_flush = apply_filters( 'w3tc_preflush_posts', true, $extras );
171
+ if ( $do_flush )
172
+ do_action( 'w3tc_flush_posts', $extras );
173
  }
174
 
175
  /**
202
  $default_actions_added = true;
203
  }
204
 
205
+ $do_flush = apply_filters( 'w3tc_preflush_all', true, $extras );
206
+ if ( $do_flush )
207
+ do_action( 'w3tc_flush_all', $extras );
208
  }
209
 
210
  /**
211
  * Purges/Flushes url from page cache, varnish and cdn cache
212
  */
213
+ function flush_url( $url, $extras = null ) {
214
+ $do_flush = apply_filters( 'w3tc_preflush_url', true, $extras );
215
+ if ( $do_flush )
216
+ do_action( 'w3tc_flush_url', $url );
217
  }
218
 
219
  /**
Cache_File_Generic.php CHANGED
@@ -2,13 +2,7 @@
2
  namespace W3TC;
3
 
4
  /**
5
- * Generic file cache
6
- */
7
-
8
-
9
-
10
- /**
11
- * class Cache_File_Generic
12
  */
13
  class Cache_File_Generic extends Cache_File {
14
  /**
@@ -56,7 +50,7 @@ class Cache_File_Generic extends Cache_File {
56
 
57
  $tmppath = $path . '.' . getmypid();
58
 
59
- $fp = @fopen( $tmppath, 'w' );
60
  if ( !$fp )
61
  return false;
62
 
@@ -83,16 +77,43 @@ class Cache_File_Generic extends Cache_File {
83
  $old_entry_path = $path . '_old';
84
  @unlink( $old_entry_path );
85
 
86
- if ( Util_Environment::is_apache() && isset( $var['headers'] ) &&
87
- isset( $var['headers']['Content-Type'] ) &&
88
- substr( $var['headers']['Content-Type'], 0, 8 ) == 'text/xml' ) {
89
- file_put_contents( dirname( $path ) . '/.htaccess',
90
- "<IfModule mod_mime.c>\n" .
91
- " RemoveType .html_gzip\n" .
92
- " AddType text/xml .html_gzip\n" .
93
- " RemoveType .html\n" .
94
- " AddType text/xml .html\n".
95
- "</IfModule>" );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  }
97
 
98
  return true;
@@ -147,7 +168,7 @@ class Cache_File_Generic extends Cache_File {
147
  if ( !is_readable( $path ) )
148
  return null;
149
 
150
- $fp = @fopen( $path, 'r' );
151
  if ( !$fp )
152
  return null;
153
 
2
  namespace W3TC;
3
 
4
  /**
5
+ * Disk:Enhanced file cache
 
 
 
 
 
 
6
  */
7
  class Cache_File_Generic extends Cache_File {
8
  /**
50
 
51
  $tmppath = $path . '.' . getmypid();
52
 
53
+ $fp = @fopen( $tmppath, 'wb' );
54
  if ( !$fp )
55
  return false;
56
 
77
  $old_entry_path = $path . '_old';
78
  @unlink( $old_entry_path );
79
 
80
+ if ( Util_Environment::is_apache() && isset( $var['headers'] ) ) {
81
+ $rules = '';
82
+
83
+ if ( isset( $var['headers']['Content-Type'] ) &&
84
+ substr( $var['headers']['Content-Type'], 0, 8 ) == 'text/xml' ) {
85
+
86
+ $rules .= "<IfModule mod_mime.c>\n";
87
+ $rules .= " RemoveType .html_gzip\n";
88
+ $rules .= " AddType text/xml .html_gzip\n";
89
+ $rules .= " RemoveType .html\n";
90
+ $rules .= " AddType text/xml .html\n";
91
+ $rules .= "</IfModule>\n";
92
+ }
93
+
94
+ if ( isset( $var['headers'] ) ) {
95
+ $links = '';
96
+
97
+ foreach ( $var['headers'] as $h ) {
98
+ if ( isset($h['n']) && isset($h['v']) && $h['n'] == 'Link' ) {
99
+ $value = $h['v'];
100
+ if ( false !== strpos( $value, 'rel=preload' ) ) {
101
+ $links .= " Header add Link '" . trim($value) . "'\n";
102
+ }
103
+ }
104
+ }
105
+
106
+ if ( !empty( $links) ) {
107
+ $rules .= "<IfModule mod_headers.c>\n";
108
+ $rules .= " Header unset Link\n";
109
+ $rules .= $links;
110
+ $rules .= "</IfModule>\n";
111
+ }
112
+ }
113
+
114
+ if ( !empty($rules) ) {
115
+ @file_put_contents( dirname( $path ) . '/.htaccess', $rules );
116
+ }
117
  }
118
 
119
  return true;
168
  if ( !is_readable( $path ) )
169
  return null;
170
 
171
+ $fp = @fopen( $path, 'rb' );
172
  if ( !$fp )
173
  return null;
174
 
Cache_Memcache.php CHANGED
@@ -44,6 +44,14 @@ class Cache_Memcache extends Cache_Base {
44
  return false;
45
  }
46
 
 
 
 
 
 
 
 
 
47
  return true;
48
  }
49
 
44
  return false;
45
  }
46
 
47
+ // when disabled - no extra requests are made to obtain key version,
48
+ // but flush operations not supported as a result
49
+ // group should be always empty
50
+ if ( isset( $config['key_version_mode'] ) &&
51
+ $config['key_version_mode'] == 'disabled' ) {
52
+ $this->_key_version[''] = 1;
53
+ }
54
+
55
  return true;
56
  }
57
 
Cache_Memcached.php CHANGED
@@ -82,6 +82,14 @@ class Cache_Memcached extends Cache_Base {
82
  $this->_memcache->setSaslAuthData( $config['username'],
83
  $config['password'] );
84
 
 
 
 
 
 
 
 
 
85
  return true;
86
  }
87
 
82
  $this->_memcache->setSaslAuthData( $config['username'],
83
  $config['password'] );
84
 
85
+ // when disabled - no extra requests are made to obtain key version,
86
+ // but flush operations not supported as a result
87
+ // group should be always empty
88
+ if ( isset( $config['key_version_mode'] ) &&
89
+ $config['key_version_mode'] == 'disabled' ) {
90
+ $this->_key_version[''] = 1;
91
+ }
92
+
93
  return true;
94
  }
95
 
Cache_Redis.php CHANGED
@@ -25,6 +25,14 @@ class Cache_Redis extends Cache_Base {
25
  $this->_servers = (array)$config['servers'];
26
  $this->_password = $config['password'];
27
  $this->_dbid = $config['dbid'];
 
 
 
 
 
 
 
 
28
  }
29
 
30
  /**
@@ -325,14 +333,16 @@ class Cache_Redis extends Cache_Base {
325
 
326
  if ( substr( $server, 0, 5 ) == 'unix:' ) {
327
  if ( $this->_persistent )
328
- $accessor->pconnect( trim( substr( $server, 5 ) ) );
 
329
  else
330
  $accessor->connect( trim( substr( $server, 5 ) ) );
331
  } else {
332
  list( $ip, $port ) = explode( ':', $server );
333
 
334
  if ( $this->_persistent )
335
- $accessor->pconnect( trim( $ip ), (integer) trim( $port ) );
 
336
  else
337
  $accessor->connect( trim( $ip ), (integer) trim( $port ) );
338
  }
25
  $this->_servers = (array)$config['servers'];
26
  $this->_password = $config['password'];
27
  $this->_dbid = $config['dbid'];
28
+
29
+ // when disabled - no extra requests are made to obtain key version,
30
+ // but flush operations not supported as a result
31
+ // group should be always empty
32
+ if ( isset( $config['key_version_mode'] ) &&
33
+ $config['key_version_mode'] == 'disabled' ) {
34
+ $this->_key_version[''] = 1;
35
+ }
36
  }
37
 
38
  /**
333
 
334
  if ( substr( $server, 0, 5 ) == 'unix:' ) {
335
  if ( $this->_persistent )
336
+ $accessor->pconnect( trim( substr( $server, 5 ) ),
337
+ null, null, $this->_instance_id . '_' . $this->_dbid );
338
  else
339
  $accessor->connect( trim( substr( $server, 5 ) ) );
340
  } else {
341
  list( $ip, $port ) = explode( ':', $server );
342
 
343
  if ( $this->_persistent )
344
+ $accessor->pconnect( trim( $ip ), (integer) trim( $port ),
345
+ null, $this->_instance_id . '_' . $this->_dbid );
346
  else
347
  $accessor->connect( trim( $ip ), (integer) trim( $port ) );
348
  }
CdnEngine.php CHANGED
@@ -67,10 +67,6 @@ class CdnEngine {
67
  $instances[$instance_key] = new CdnEngine_Mirror( $config );
68
  break;
69
 
70
- case 'netdna':
71
- $instances[$instance_key] = new CdnEngine_Mirror_Netdna( $config );
72
- break;
73
-
74
  case 'rackspace_cdn':
75
  $instances[$instance_key] = new CdnEngine_Mirror_RackSpaceCdn( $config );
76
  break;
67
  $instances[$instance_key] = new CdnEngine_Mirror( $config );
68
  break;
69
 
 
 
 
 
70
  case 'rackspace_cdn':
71
  $instances[$instance_key] = new CdnEngine_Mirror_RackSpaceCdn( $config );
72
  break;
CdnEngine_Azure.php CHANGED
@@ -90,10 +90,15 @@ class CdnEngine_Azure extends CdnEngine_Base {
90
  }
91
 
92
  foreach ( $files as $file ) {
93
- if ( !is_null( $timeout_time ) && time() > $timeout_time )
94
- break;
95
-
96
  $remote_path = $file['remote_path'];
 
 
 
 
 
 
 
 
97
 
98
  $results[] = $this->_upload( $file, $force_rewrite );
99
  }
90
  }
91
 
92
  foreach ( $files as $file ) {
 
 
 
93
  $remote_path = $file['remote_path'];
94
+ $local_path = $file['local_path'];
95
+
96
+ // process at least one item before timeout so that progress goes on
97
+ if ( !empty( $results ) ) {
98
+ if ( !is_null( $timeout_time ) && time() > $timeout_time ) {
99
+ return 'timeout';
100
+ }
101
+ }
102
 
103
  $results[] = $this->_upload( $file, $force_rewrite );
104
  }
CdnEngine_Base.php CHANGED
@@ -179,7 +179,15 @@ class CdnEngine_Base {
179
  break;
180
 
181
  default:
182
- if ( $count > 4 ) {
 
 
 
 
 
 
 
 
183
  $domain = $this->_get_domain( array_slice( $domains, 4 ),
184
  $path );
185
  } else {
@@ -579,6 +587,10 @@ class CdnEngine_Base {
579
  */
580
  function _get_domain( $domains, $path ) {
581
  $count = count( $domains );
 
 
 
 
582
 
583
  if ( $count ) {
584
  /**
179
  break;
180
 
181
  default:
182
+ if ( !isset( $domains[0] ) ) {
183
+ $scheme = $this->_get_scheme();
184
+ if ( 'https' == $scheme && isset( $domains['https_default'] ) ) {
185
+ return $domains['https_default'];
186
+ } else {
187
+ return isset( $domains['http_default'] ) ? $domains['http_default'] :
188
+ $domains['https_default'];
189
+ }
190
+ } elseif ( $count > 4 ) {
191
  $domain = $this->_get_domain( array_slice( $domains, 4 ),
192
  $path );
193
  } else {
587
  */
588
  function _get_domain( $domains, $path ) {
589
  $count = count( $domains );
590
+ if ( isset( $domains['http_default'] ) )
591
+ $count--;
592
+ if ( isset( $domains['https_default'] ) )
593
+ $count--;
594
 
595
  if ( $count ) {
596
  /**
CdnEngine_Ftp.php CHANGED
@@ -164,12 +164,16 @@ class CdnEngine_Ftp extends CdnEngine_Base {
164
  }
165
 
166
  foreach ( $files as $file ) {
167
- if ( !is_null( $timeout_time ) && time() > $timeout_time )
168
- break;
169
-
170
  $local_path = $file['local_path'];
171
  $remote_path = $file['remote_path'];
172
 
 
 
 
 
 
 
 
173
  if ( !file_exists( $local_path ) ) {
174
  $results[] = $this->_get_result( $local_path, $remote_path,
175
  W3TC_CDN_RESULT_ERROR, 'Source file not found.', $file );
164
  }
165
 
166
  foreach ( $files as $file ) {
 
 
 
167
  $local_path = $file['local_path'];
168
  $remote_path = $file['remote_path'];
169
 
170
+ // process at least one item before timeout so that progress goes on
171
+ if ( !empty( $results ) ) {
172
+ if ( !is_null( $timeout_time ) && time() > $timeout_time ) {
173
+ return 'timeout';
174
+ }
175
+ }
176
+
177
  if ( !file_exists( $local_path ) ) {
178
  $results[] = $this->_get_result( $local_path, $remote_path,
179
  W3TC_CDN_RESULT_ERROR, 'Source file not found.', $file );
CdnEngine_GoogleDrive.php CHANGED
@@ -11,6 +11,7 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
11
  private $_root_url;
12
 
13
  private $_service;
 
14
 
15
 
16
 
@@ -28,6 +29,9 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
28
  $this->_root_url = rtrim( $config['root_url'], '/' ) . '/';
29
  $this->_new_access_token_callback = $config['new_access_token_callback'];
30
 
 
 
 
31
  try {
32
  $this->_init_service( $config['access_token'] );
33
  } catch ( \Exception $e ) {
@@ -79,7 +83,7 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
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
 
@@ -96,8 +100,10 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
96
  }
97
  if ( $r != 'success' )
98
  $result = false;
99
- if ( $r == 'timeout' )
100
- break;
 
 
101
  }
102
 
103
  return $result;
@@ -105,6 +111,45 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
105
 
106
 
107
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  private function _upload_chunk( $files, &$results, $force_rewrite,
109
  $timeout_time, $allow_refresh_token ) {
110
  list( $result, $listed_files ) = $this->list_files_chunk( $files,
@@ -112,45 +157,28 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
112
  if ( $result != 'success' )
113
  return $result;
114
 
115
- // remove dups
116
- $files_by_title = array();
117
-
118
- for ( $n = 0; $n < count( $listed_files ); $n++ ) {
119
- $title_to_search = $listed_files[$n]->title;
120
- $files_by_title[$title_to_search] = $listed_files[$n];
121
-
122
- for ( $m = $n + 1; $m < count( $listed_files ); $m++ ) {
123
- if ( $listed_files[$m]->title == $title_to_search ) {
124
- try {
125
- $this->_service->files->delete( $listed_files[$m]->id );
126
- } catch ( \W3TCG_Google_Service_Exception $e ) {
127
- $errors = $e->getErrors();
128
- $details = '';
129
- if ( count( $errors ) >= 1 ) {
130
- if ( $errors[0]['reason'] == 'notFound' ) {
131
- continue;
132
- } else
133
- $details = $errors[0]['reason'];
134
- }
135
 
136
- $results[] = $this->_get_result( '',
137
- '', W3TC_CDN_RESULT_ERROR,
138
- 'Failed to delete dup file ' . $title_to_search . ' ' . $details );
139
- $result = 'with_errors';
140
- }
141
- }
142
  }
143
  }
144
 
145
  // check update date and upload
146
  foreach ( $files as $file_descriptor ) {
147
- if ( !is_null( $timeout_time ) && time() > $timeout_time )
148
- return 'timeout';
 
 
 
 
 
149
 
150
  list( $parent_id, $title ) = $this->remote_path_to_title(
151
  $file_descriptor['remote_path'] );
152
- $properties = array();
153
-
154
  if ( isset( $file_descriptor['content'] ) ) {
155
  // when content specified - just upload
156
  $content = $file_descriptor['content'];
@@ -158,7 +186,7 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
158
  $local_path = $file_descriptor['local_path'];
159
  if ( !file_exists( $local_path ) ) {
160
  $results[] = $this->_get_result( $local_path,
161
- $file_descriptor['remote_path'],
162
  W3TC_CDN_RESULT_ERROR, 'Source file not found.',
163
  $file_descriptor );
164
  continue;
@@ -171,8 +199,8 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
171
  $p->value = $mtime;
172
  $properties[] = $p;
173
 
174
- if ( !$force_rewrite && isset( $files_by_title[$title] ) ) {
175
- $existing_file = $files_by_title[$title];
176
  $existing_size = $existing_file->fileSize;
177
  $existing_mtime = 0;
178
  if ( is_array( $existing_file->properties ) ) {
@@ -185,7 +213,7 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
185
  $size = @filesize( $local_path );
186
  if ( $mtime == $existing_mtime && $size == $existing_size ) {
187
  $results[] = $this->_get_result( $file_descriptor['local_path'],
188
- $file_descriptor['remote_path'], W3TC_CDN_RESULT_OK,
189
  'File up-to-date.', $file_descriptor );
190
  continue;
191
  }
@@ -205,8 +233,8 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
205
  try {
206
  try {
207
  // update file if there's one already or insert
208
- if ( isset( $files_by_title[$title] ) ) {
209
- $existing_file = $files_by_title[$title];
210
 
211
  $created_file = $this->_service->files->update(
212
  $existing_file->id, $file, array(
@@ -235,20 +263,21 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
235
  }
236
 
237
  $results[] = $this->_get_result( $file_descriptor['local_path'],
238
- $file_descriptor['remote_path'], W3TC_CDN_RESULT_OK,
239
  'OK', $file_descriptor );
 
240
  } catch ( \W3TCG_Google_Service_Exception $e ) {
241
  $errors = $e->getErrors();
242
  $details = '';
243
  if ( count( $errors ) >= 1 ) {
244
- $details = $errors[0]['reason'];
245
  }
246
 
247
  delete_transient( 'w3tc_cdn_google_drive_folder_ids' );
248
 
249
  $results[] = $this->_get_result( $file_descriptor['local_path'],
250
- $file_descriptor['remote_path'], W3TC_CDN_RESULT_ERROR,
251
- 'Failed to upload file ' . $file_descriptor['remote_path'] .
252
  ' ' . $details, $file_descriptor );
253
  $result = 'with_errors';
254
  continue;
@@ -256,8 +285,8 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
256
  delete_transient( 'w3tc_cdn_google_drive_folder_ids' );
257
 
258
  $results[] = $this->_get_result( $file_descriptor['local_path'],
259
- $file_descriptor['remote_path'], W3TC_CDN_RESULT_ERROR,
260
- 'Failed to upload file ' . $file_descriptor['remote_path'],
261
  $file_descriptor );
262
  $result = 'with_errors';
263
  continue;
@@ -516,7 +545,77 @@ class CdnEngine_GoogleDrive extends CdnEngine_Base {
516
  }
517
 
518
 
519
- function format_url( $path ) {
520
- return $this->_root_url . ltrim( $path, '/' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
521
  }
522
  }
11
  private $_root_url;
12
 
13
  private $_service;
14
+ private $_tablename_pathmap;
15
 
16
 
17
 
29
  $this->_root_url = rtrim( $config['root_url'], '/' ) . '/';
30
  $this->_new_access_token_callback = $config['new_access_token_callback'];
31
 
32
+ global $wpdb;
33
+ $this->_tablename_pathmap = $wpdb->base_prefix . W3TC_CDN_TABLE_PATHMAP;
34
+
35
  try {
36
  $this->_init_service( $config['access_token'] );
37
  } catch ( \Exception $e ) {
83
  function upload( $files, &$results, $force_rewrite = false, $timeout_time = NULL ) {
84
  if ( is_null( $this->_service ) )
85
  return false;
86
+
87
  $allow_refresh_token = true;
88
  $result = true;
89
 
100
  }
101
  if ( $r != 'success' )
102
  $result = false;
103
+ if ( $r == 'timeout' ) {
104
+ return 'timeout';
105
+ }
106
+
107
  }
108
 
109
  return $result;
111
 
112
 
113
 
114
+ private function _properties_to_path( $file ) {
115
+ $path_pieces = array();
116
+ foreach ( $file->properties as $p ) {
117
+ $k = ($p->key == 'path') ? 'path1' : $p->key;
118
+ if ( !preg_match( '/^path[0-9]+$/', $k ) )
119
+ continue;
120
+ $path_pieces[$k] = $p->value;
121
+ }
122
+ if ( count( $path_pieces ) == 0 )
123
+ return NULL;
124
+ ksort($path_pieces);
125
+ return join( $path_pieces );
126
+ }
127
+
128
+
129
+
130
+ private function _path_to_properties( $path ) {
131
+ // from google drive api docs:
132
+ // Maximum of 124 bytes size per property
133
+ // (including both key and value) string in UTF-8 encoding.
134
+ // Maximum of 30 private properties per file from any one application.
135
+ $chunks = str_split( $path, 55 );
136
+ $properties = array();
137
+ $i = 1;
138
+
139
+ foreach ( $chunks as $chunk ) {
140
+ $p = new \W3TCG_Google_Service_Drive_Property();
141
+ $p->key = 'path' . $i;
142
+ $p->value = $chunk;
143
+ $properties[] = $p;
144
+
145
+ $i++;
146
+ }
147
+
148
+ return $properties;
149
+ }
150
+
151
+
152
+
153
  private function _upload_chunk( $files, &$results, $force_rewrite,
154
  $timeout_time, $allow_refresh_token ) {
155
  list( $result, $listed_files ) = $this->list_files_chunk( $files,
157
  if ( $result != 'success' )
158
  return $result;
159
 
160
+ $files_by_path = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
+ foreach ( $listed_files as $existing_file ) {
163
+ $path = $this->_properties_to_path( $existing_file );
164
+ if ( $path ) {
165
+ $files_by_path[$path] = $existing_file;
 
 
166
  }
167
  }
168
 
169
  // check update date and upload
170
  foreach ( $files as $file_descriptor ) {
171
+ $remote_path = $file_descriptor['remote_path'];
172
+
173
+ // process at least one item before timeout so that progress goes on
174
+ if ( !empty( $results ) ) {
175
+ if ( !is_null( $timeout_time ) && time() > $timeout_time )
176
+ return 'timeout';
177
+ }
178
 
179
  list( $parent_id, $title ) = $this->remote_path_to_title(
180
  $file_descriptor['remote_path'] );
181
+ $properties = $this->_path_to_properties( $remote_path );
 
182
  if ( isset( $file_descriptor['content'] ) ) {
183
  // when content specified - just upload
184
  $content = $file_descriptor['content'];
186
  $local_path = $file_descriptor['local_path'];
187
  if ( !file_exists( $local_path ) ) {
188
  $results[] = $this->_get_result( $local_path,
189
+ $remote_path,
190
  W3TC_CDN_RESULT_ERROR, 'Source file not found.',
191
  $file_descriptor );
192
  continue;
199
  $p->value = $mtime;
200
  $properties[] = $p;
201
 
202
+ if ( !$force_rewrite && isset( $files_by_path[$remote_path] ) ) {
203
+ $existing_file = $files_by_path[$remote_path];
204
  $existing_size = $existing_file->fileSize;
205
  $existing_mtime = 0;
206
  if ( is_array( $existing_file->properties ) ) {
213
  $size = @filesize( $local_path );
214
  if ( $mtime == $existing_mtime && $size == $existing_size ) {
215
  $results[] = $this->_get_result( $file_descriptor['local_path'],
216
+ $remote_path, W3TC_CDN_RESULT_OK,
217
  'File up-to-date.', $file_descriptor );
218
  continue;
219
  }
233
  try {
234
  try {
235
  // update file if there's one already or insert
236
+ if ( isset( $files_by_path[$remote_path] ) ) {
237
+ $existing_file = $files_by_path[$remote_path];
238
 
239
  $created_file = $this->_service->files->update(
240
  $existing_file->id, $file, array(
263
  }
264
 
265
  $results[] = $this->_get_result( $file_descriptor['local_path'],
266
+ $remote_path, W3TC_CDN_RESULT_OK,
267
  'OK', $file_descriptor );
268
+ $this->path_set_id( $remote_path, $created_file->id );
269
  } catch ( \W3TCG_Google_Service_Exception $e ) {
270
  $errors = $e->getErrors();
271
  $details = '';
272
  if ( count( $errors ) >= 1 ) {
273
+ $details = json_encode($errors);
274
  }
275
 
276
  delete_transient( 'w3tc_cdn_google_drive_folder_ids' );
277
 
278
  $results[] = $this->_get_result( $file_descriptor['local_path'],
279
+ $remote_path, W3TC_CDN_RESULT_ERROR,
280
+ 'Failed to upload file ' . $remote_path .
281
  ' ' . $details, $file_descriptor );
282
  $result = 'with_errors';
283
  continue;
285
  delete_transient( 'w3tc_cdn_google_drive_folder_ids' );
286
 
287
  $results[] = $this->_get_result( $file_descriptor['local_path'],
288
+ $remote_path, W3TC_CDN_RESULT_ERROR,
289
+ 'Failed to upload file ' . $remote_path,
290
  $file_descriptor );
291
  $result = 'with_errors';
292
  continue;
545
  }
546
 
547
 
548
+
549
+ function purge_all( &$results ) {
550
+ return false;
551
+ }
552
+
553
+
554
+
555
+ private function path_set_id( $path, $id ) {
556
+ global $wpdb;
557
+ $md5 = md5( $path );
558
+ if ( !$id ) {
559
+ $sql = "
560
+ INSERT INTO $this->_tablename_pathmap (path, path_hash, remote_id)
561
+ VALUES (%s, %s, NULL)
562
+ ON DUPLICATE KEY UPDATE remote_id = NULL";
563
+ $wpdb->query($wpdb->prepare($sql, $path, $md5));
564
+ } else {
565
+ $sql = "
566
+ INSERT INTO $this->_tablename_pathmap (path, path_hash, remote_id)
567
+ VALUES (%s, %s, %s)
568
+ ON DUPLICATE KEY UPDATE remote_id = %s";
569
+ $wpdb->query($wpdb->prepare(
570
+ $sql, $path, $md5, $id, $id));
571
+ }
572
+ }
573
+
574
+
575
+
576
+ private function path_get_id( $path, $allow_refresh_token = true ) {
577
+ global $wpdb;
578
+ $md5 = md5($path);
579
+ $sql = "SELECT remote_id FROM $this->_tablename_pathmap WHERE path_hash = %s";
580
+ $query = $wpdb->prepare( $sql, $md5 );
581
+ $results = $wpdb->get_results( $query );
582
+ if ( count( $results ) > 0 ) {
583
+ return $results[0]->remote_id;
584
+ }
585
+ $props = $this->_path_to_properties( $path );
586
+ $q = 'trashed = false';
587
+ foreach ( $props as $prop ) {
588
+ $key = $prop->key;
589
+ $value = str_replace( "'", "\\'", $prop->value );
590
+ $q .= " and properties has { key='$key' and " .
591
+ " value='$value' and visibility='PRIVATE' }";
592
+ }
593
+
594
+ try {
595
+ $items = $this->_service->files->listFiles(
596
+ array( 'q' => $q ) );
597
+ } catch ( \W3TCG_Google_Auth_Exception $e ) {
598
+ if ( $allow_refresh_token ) {
599
+ $this->_refresh_token();
600
+ return $this->path_get_id( $path, false );
601
+ }
602
+
603
+ throw $e;
604
+ }
605
+
606
+ $id = ( count( $items ) == 0 ) ? NULL : $items[0]->id;
607
+ $this->path_set_id( $path, $id );
608
+
609
+ return $id;
610
+ }
611
+
612
+
613
+
614
+ function format_url( $path, $allow_refresh_token = true ) {
615
+ $id = $this->path_get_id( Util_Environment::remove_query( $path ) );
616
+ if ( is_null( $id ) )
617
+ return NULL;
618
+
619
+ return 'https://drive.google.com/uc?id=' . $id;
620
  }
621
  }
CdnEngine_Mirror_Akamai.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace W3TC;
3
 
4
- /**
5
- * W3 CDN Netdna Class
6
- */
7
-
8
  define( 'W3TC_CDN_MIRROR_AKAMAI_WSDL', 'https://ccuapi.akamai.com/ccuapi-axis.wsdl' );
9
  define( 'W3TC_CDN_MIRROR_AKAMAI_NAMESPACE', 'http://www.akamai.com/purge' );
10
 
1
  <?php
2
  namespace W3TC;
3
 
 
 
 
 
4
  define( 'W3TC_CDN_MIRROR_AKAMAI_WSDL', 'https://ccuapi.akamai.com/ccuapi-axis.wsdl' );
5
  define( 'W3TC_CDN_MIRROR_AKAMAI_NAMESPACE', 'http://www.akamai.com/purge' );
6
 
CdnEngine_Mirror_Cotendo.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace W3TC;
3
 
4
- /**
5
- * W3 CDN Netdna Class
6
- */
7
-
8
  define( 'W3TC_CDN_MIRROR_COTENDO_WSDL', 'https://api.cotendo.net/cws?wsdl' );
9
  define( 'W3TC_CDN_MIRROR_COTENDO_ENDPOINT', 'http://api.cotendo.net/cws?ver=1.0' );
10
  define( 'W3TC_CDN_MIRROR_COTENDO_NAMESPACE', 'http://api.cotendo.net/' );
1
  <?php
2
  namespace W3TC;
3
 
 
 
 
 
4
  define( 'W3TC_CDN_MIRROR_COTENDO_WSDL', 'https://api.cotendo.net/cws?wsdl' );
5
  define( 'W3TC_CDN_MIRROR_COTENDO_ENDPOINT', 'http://api.cotendo.net/cws?ver=1.0' );
6
  define( 'W3TC_CDN_MIRROR_COTENDO_NAMESPACE', 'http://api.cotendo.net/' );
CdnEngine_Mirror_Edgecast.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace W3TC;
3
 
4
- /**
5
- * W3 CDN Netdna Class
6
- */
7
-
8
  if ( !defined( 'W3TC_CDN_EDGECAST_PURGE_URL' ) ) define( 'W3TC_CDN_EDGECAST_PURGE_URL', 'http://api.edgecast.com/v2/mcc/customers/%s/edge/purge' );
9
  define( 'W3TC_CDN_EDGECAST_MEDIATYPE_WINDOWS_MEDIA_STREAMING', 1 );
10
  define( 'W3TC_CDN_EDGECAST_MEDIATYPE_FLASH_MEDIA_STREAMING', 2 );
1
  <?php
2
  namespace W3TC;
3
 
 
 
 
 
4
  if ( !defined( 'W3TC_CDN_EDGECAST_PURGE_URL' ) ) define( 'W3TC_CDN_EDGECAST_PURGE_URL', 'http://api.edgecast.com/v2/mcc/customers/%s/edge/purge' );
5
  define( 'W3TC_CDN_EDGECAST_MEDIATYPE_WINDOWS_MEDIA_STREAMING', 1 );
6
  define( 'W3TC_CDN_EDGECAST_MEDIATYPE_FLASH_MEDIA_STREAMING', 2 );
CdnEngine_Mirror_MaxCdn.php CHANGED
@@ -1,7 +1,171 @@
1
  <?php
2
  namespace W3TC;
3
 
4
- /**
5
- * W3 CDN MaxCDN Class
6
- */
7
- class CdnEngine_Mirror_MaxCdn extends CdnEngine_Mirror_Netdna {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
  namespace W3TC;
3
 
4
+ define( 'W3TC_CDN_NETDNA_URL', 'netdna-cdn.com' );
5
+
6
+ class CdnEngine_Mirror_MaxCdn extends CdnEngine_Mirror {
7
+ /**
8
+ * PHP5 Constructor
9
+ *
10
+ * @param array $config
11
+ */
12
+ function __construct( $config = array() ) {
13
+ $config = array_merge( array(
14
+ 'authorization_key' => '',
15
+ 'alias' => '',
16
+ 'consumerkey' => '',
17
+ 'consumersecret' => '',
18
+ 'zone_id' => 0
19
+ ), $config );
20
+ $split_keys = explode( '+', $config['authorization_key'] );
21
+ if ( sizeof( $split_keys )==3 )
22
+ list( $config['alias'], $config['consumerkey'], $config['consumersecret'] ) = $split_keys;
23
+ parent::__construct( $config );
24
+ }
25
+
26
+ /**
27
+ * Purges remote files
28
+ *
29
+ * @param array $files
30
+ * @param array $results
31
+ * @return boolean
32
+ */
33
+ function purge( $files, &$results ) {
34
+ if ( empty( $this->_config['authorization_key'] ) ) {
35
+ $results = $this->_get_results( $files, W3TC_CDN_RESULT_HALT, __( 'Empty Authorization Key.', 'w3-total-cache' ) );
36
+
37
+ return false;
38
+ }
39
+
40
+ if ( empty( $this->_config['alias'] ) || empty( $this->_config['consumerkey'] ) || empty( $this->_config['consumersecret'] ) ) {
41
+ $results = $this->_get_results( $files, W3TC_CDN_RESULT_HALT, __( 'Malformed Authorization Key.', 'w3-total-cache' ) );
42
+
43
+ return false;
44
+ }
45
+
46
+ if ( !class_exists( 'NetDNA' ) ) {
47
+ require_once W3TC_LIB_NETDNA_DIR . '/NetDNA.php';
48
+ }
49
+
50
+ $api = new \NetDNA( $this->_config['alias'],
51
+ $this->_config['consumerkey'], $this->_config['consumersecret'] );
52
+ $results = array();
53
+
54
+ try {
55
+ if ( $this->_config['zone_id'] != 0 )
56
+ $zone_id = $this->_config['zone_id'];
57
+ else {
58
+ $zone_id = $api->get_zone_id( get_home_url() );
59
+ }
60
+
61
+ if ( $zone_id == 0 ) {
62
+ $zone_id = $api->get_zone_id( Util_Environment::home_domain_root_url() );
63
+ }
64
+
65
+ if ( $zone_id == 0 ) {
66
+ $zone_id = $api->get_zone_id( str_replace( '://', '://www.', Util_Environment::home_domain_root_url() ) );
67
+ }
68
+
69
+ if ( $zone_id == 0 || is_null( $zone_id ) ) {
70
+ if ( Util_Environment::home_domain_root_url() == get_home_url() )
71
+ $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, sprintf( __( 'No zones match site: %s.', 'w3-total-cache' ), trim( get_home_url(), '/' ) ) );
72
+ else
73
+ $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, sprintf( __( 'No zones match site: %s or %s.', 'w3-total-cache' ), trim( get_home_url(), '/' ), trim( Util_Environment::home_domain_root_url(), '/' ) ) );
74
+ return !$this->_is_error( $results );
75
+ }
76
+
77
+
78
+ $files_to_pass = array();
79
+ foreach ( $files as $file )
80
+ $files_to_pass[] = '/' . $file['remote_path'];
81
+ $params = array( 'files' => $files_to_pass );
82
+ $file_purge = json_decode( $api->delete(
83
+ '/zones/pull.json/' . $zone_id . '/cache',
84
+ $params ) );
85
+
86
+ if ( preg_match( "(200|201)", $file_purge->code ) ) {
87
+ $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_OK, 'OK' );
88
+ } else {
89
+ if ( preg_match( "(401|500)", $file_purge->code ) ) {
90
+ $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, sprintf( __( 'Failed with error code %s Please check your alias, consumer key, and private key.', 'w3-total-cache' ), $file_purge->code ) );
91
+ } else {
92
+ $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, __( 'Failed with error code ', 'w3-total-cache' ) . $file_purge->code );
93
+ }
94
+ }
95
+ } catch ( W3tcWpHttpException $e ) {
96
+ $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_HALT, __( 'Failure to pull zone: ', 'w3-total-cache' ) . $e->getMessage() );
97
+ }
98
+
99
+ return !$this->_is_error( $results );
100
+ }
101
+
102
+ /**
103
+ * Purge CDN completely
104
+ *
105
+ * @param unknown $results
106
+ * @return bool
107
+ */
108
+ function purge_all( &$results ) {
109
+ if ( empty( $this->_config['authorization_key'] ) ) {
110
+ $results = $this->_get_results( array(), W3TC_CDN_RESULT_HALT, __( 'Empty Authorization Key.', 'w3-total-cache' ) );
111
+
112
+ return false;
113
+ }
114
+
115
+ if ( empty( $this->_config['alias'] ) || empty( $this->_config['consumerkey'] ) || empty( $this->_config['consumersecret'] ) ) {
116
+ $results = $this->_get_results( array(), W3TC_CDN_RESULT_HALT, __( 'Malformed Authorization Key.', 'w3-total-cache' ) );
117
+
118
+ return false;
119
+ }
120
+
121
+ if ( !class_exists( 'NetDNA' ) ) {
122
+ require_once W3TC_LIB_NETDNA_DIR . '/NetDNA.php';
123
+ }
124
+
125
+ $api = new \NetDNA( $this->_config['alias'], $this->_config['consumerkey'], $this->_config['consumersecret'] );
126
+
127
+ $results = array();
128
+
129
+ try {
130
+ if ( $this->_config['zone_id'] != 0 )
131
+ $zone_id = $this->_config['zone_id'];
132
+ else {
133
+ $zone_id = $api->get_zone_id( get_home_url() );
134
+ }
135
+
136
+ if ( $zone_id == 0 ) {
137
+ $zone_id = $api->get_zone_id( Util_Environment::home_domain_root_url() );
138
+ }
139
+
140
+
141
+ if ( $zone_id == 0 ) {
142
+ $zone_id = $api->get_zone_id( str_replace( '://', '://www.', Util_Environment::home_domain_root_url() ) );
143
+ }
144
+
145
+ if ( $zone_id == 0 || is_null( $zone_id ) ) {
146
+ if ( Util_Environment::home_domain_root_url() == get_home_url() )
147
+ $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, sprintf( __( 'No zones match site: %s.', 'w3-total-cache' ), trim( get_home_url(), '/' ) ) );
148
+ else
149
+ $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, sprintf( __( 'No zones match site: %s or %s.', 'w3-total-cache' ), trim( get_home_url(), '/' ), trim( Util_Environment::home_domain_root_url(), '/' ) ) );
150
+ return !$this->_is_error( $results );
151
+ }
152
+
153
+ $file_purge = json_decode( $api->delete( '/zones/pull.json/' . $zone_id . '/cache' ) );
154
+
155
+ if ( preg_match( "(200|201)", $file_purge->code ) ) {
156
+ $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_OK, __( 'OK', 'w3-total-cache' ) );
157
+ } else {
158
+ if ( preg_match( "(401|500)", $file_purge->code ) ) {
159
+ $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, sprintf( __( 'Failed with error code %s. Please check your alias, consumer key, and private key.', 'w3-total-cache' ), $file_purge->code ) );
160
+ } else {
161
+ $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, __( 'Failed with error code ', 'w3-total-cache' ) . $file_purge->code );
162
+ }
163
+ }
164
+
165
+ } catch ( W3tcWpHttpException $e ) {
166
+ $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_HALT, __( 'Failure to pull zone: ', 'w3-total-cache' ) . $e->getMessage() );
167
+ }
168
+
169
+ return !$this->_is_error( $results );
170
+ }
171
+ }
CdnEngine_Mirror_Netdna.php DELETED
@@ -1,178 +0,0 @@
1
- <?php
2
- namespace W3TC;
3
-
4
- /**
5
- * W3 CDN Netdna Class
6
- */
7
-
8
- define( 'W3TC_CDN_NETDNA_URL', 'netdna-cdn.com' );
9
-
10
- /**
11
- * class CdnEngine_Mirror_Netdna
12
- */
13
- class CdnEngine_Mirror_Netdna extends CdnEngine_Mirror {
14
- /**
15
- * PHP5 Constructor
16
- *
17
- * @param array $config
18
- */
19
- function __construct( $config = array() ) {
20
- $config = array_merge( array(
21
- 'authorization_key' => '',
22
- 'alias' => '',
23
- 'consumerkey' => '',
24
- 'consumersecret' => '',
25
- 'zone_id' => 0
26
- ), $config );
27
- $split_keys = explode( '+', $config['authorization_key'] );
28
- if ( sizeof( $split_keys )==3 )
29
- list( $config['alias'], $config['consumerkey'], $config['consumersecret'] ) = $split_keys;
30
- parent::__construct( $config );
31
- }
32
-
33
- /**
34
- * Purges remote files
35
- *
36
- * @param array $files
37
- * @param array $results
38
- * @return boolean
39
- */
40
- function purge( $files, &$results ) {
41
- if ( empty( $this->_config['authorization_key'] ) ) {
42
- $results = $this->_get_results( $files, W3TC_CDN_RESULT_HALT, __( 'Empty Authorization Key.', 'w3-total-cache' ) );
43
-
44
- return false;
45
- }
46
-
47
- if ( empty( $this->_config['alias'] ) || empty( $this->_config['consumerkey'] ) || empty( $this->_config['consumersecret'] ) ) {
48
- $results = $this->_get_results( $files, W3TC_CDN_RESULT_HALT, __( 'Malformed Authorization Key.', 'w3-total-cache' ) );
49
-
50
- return false;
51
- }
52
-
53
- if ( !class_exists( 'NetDNA' ) ) {
54
- require_once W3TC_LIB_NETDNA_DIR . '/NetDNA.php';
55
- }
56
-
57
- $api = new \NetDNA( $this->_config['alias'],
58
- $this->_config['consumerkey'], $this->_config['consumersecret'] );
59
- $results = array();
60
-
61
- try {
62
- if ( $this->_config['zone_id'] != 0 )
63
- $zone_id = $this->_config['zone_id'];
64
- else {
65
- $zone_id = $api->get_zone_id( get_home_url() );
66
- }
67
-
68
- if ( $zone_id == 0 ) {
69
- $zone_id = $api->get_zone_id( Util_Environment::home_domain_root_url() );
70
- }
71
-
72
- if ( $zone_id == 0 ) {
73
- $zone_id = $api->get_zone_id( str_replace( '://', '://www.', Util_Environment::home_domain_root_url() ) );
74
- }
75
-
76
- if ( $zone_id == 0 || is_null( $zone_id ) ) {
77
- if ( Util_Environment::home_domain_root_url() == get_home_url() )
78
- $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, sprintf( __( 'No zones match site: %s.', 'w3-total-cache' ), trim( get_home_url(), '/' ) ) );
79
- else
80
- $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, sprintf( __( 'No zones match site: %s or %s.', 'w3-total-cache' ), trim( get_home_url(), '/' ), trim( Util_Environment::home_domain_root_url(), '/' ) ) );
81
- return !$this->_is_error( $results );
82
- }
83
-
84
-
85
- $files_to_pass = array();
86
- foreach ( $files as $file )
87
- $files_to_pass[] = '/' . $file['remote_path'];
88
- $params = array( 'files' => $files_to_pass );
89
- $file_purge = json_decode( $api->delete(
90
- '/zones/pull.json/' . $zone_id . '/cache',
91
- $params ) );
92
-
93
- if ( preg_match( "(200|201)", $file_purge->code ) ) {
94
- $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_OK, 'OK' );
95
- } else {
96
- if ( preg_match( "(401|500)", $file_purge->code ) ) {
97
- $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, sprintf( __( 'Failed with error code %s Please check your alias, consumer key, and private key.', 'w3-total-cache' ), $file_purge->code ) );
98
- } else {
99
- $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, __( 'Failed with error code ', 'w3-total-cache' ) . $file_purge->code );
100
- }
101
- }
102
- } catch ( W3tcWpHttpException $e ) {
103
- $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_HALT, __( 'Failure to pull zone: ', 'w3-total-cache' ) . $e->getMessage() );
104
- }
105
-
106
- return !$this->_is_error( $results );
107
- }
108
-
109
- /**
110
- * Purge CDN completely
111
- *
112
- * @param unknown $results
113
- * @return bool
114
- */
115
- function purge_all( &$results ) {
116
- if ( empty( $this->_config['authorization_key'] ) ) {
117
- $results = $this->_get_results( array(), W3TC_CDN_RESULT_HALT, __( 'Empty Authorization Key.', 'w3-total-cache' ) );
118
-
119
- return false;
120
- }
121
-
122
- if ( empty( $this->_config['alias'] ) || empty( $this->_config['consumerkey'] ) || empty( $this->_config['consumersecret'] ) ) {
123
- $results = $this->_get_results( array(), W3TC_CDN_RESULT_HALT, __( 'Malformed Authorization Key.', 'w3-total-cache' ) );
124
-
125
- return false;
126
- }
127
-
128
- if ( !class_exists( 'NetDNA' ) ) {
129
- require_once W3TC_LIB_NETDNA_DIR . '/NetDNA.php';
130
- }
131
-
132
- $api = new \NetDNA( $this->_config['alias'], $this->_config['consumerkey'], $this->_config['consumersecret'] );
133
-
134
- $results = array();
135
-
136
- try {
137
- if ( $this->_config['zone_id'] != 0 )
138
- $zone_id = $this->_config['zone_id'];
139
- else {
140
- $zone_id = $api->get_zone_id( get_home_url() );
141
- }
142
-
143
- if ( $zone_id == 0 ) {
144
- $zone_id = $api->get_zone_id( Util_Environment::home_domain_root_url() );
145
- }
146
-
147
-
148
- if ( $zone_id == 0 ) {
149
- $zone_id = $api->get_zone_id( str_replace( '://', '://www.', Util_Environment::home_domain_root_url() ) );
150
- }
151
-
152
- if ( $zone_id == 0 || is_null( $zone_id ) ) {
153
- if ( Util_Environment::home_domain_root_url() == get_home_url() )
154
- $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, sprintf( __( 'No zones match site: %s.', 'w3-total-cache' ), trim( get_home_url(), '/' ) ) );
155
- else
156
- $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, sprintf( __( 'No zones match site: %s or %s.', 'w3-total-cache' ), trim( get_home_url(), '/' ), trim( Util_Environment::home_domain_root_url(), '/' ) ) );
157
- return !$this->_is_error( $results );
158
- }
159
-
160
- $file_purge = json_decode( $api->delete( '/zones/pull.json/' . $zone_id . '/cache' ) );
161
-
162
- if ( preg_match( "(200|201)", $file_purge->code ) ) {
163
- $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_OK, __( 'OK', 'w3-total-cache' ) );
164
- } else {
165
- if ( preg_match( "(401|500)", $file_purge->code ) ) {
166
- $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, sprintf( __( 'Failed with error code %s. Please check your alias, consumer key, and private key.', 'w3-total-cache' ), $file_purge->code ) );
167
- } else {
168
- $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_ERROR, __( 'Failed with error code ', 'w3-total-cache' ) . $file_purge->code );
169
- }
170
- }
171
-
172
- } catch ( W3tcWpHttpException $e ) {
173
- $results[] = $this->_get_result( '', '', W3TC_CDN_RESULT_HALT, __( 'Failure to pull zone: ', 'w3-total-cache' ) . $e->getMessage() );
174
- }
175
-
176
- return !$this->_is_error( $results );
177
- }
178
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
CdnEngine_RackSpaceCloudFiles.php CHANGED
@@ -145,12 +145,16 @@ class CdnEngine_RackSpaceCloudFiles extends CdnEngine_Base {
145
  function upload( $files, &$results, $force_rewrite = false,
146
  $timeout_time = NULL ) {
147
  foreach ( $files as $file ) {
148
- if ( !is_null( $timeout_time ) && time() > $timeout_time )
149
- break;
150
-
151
  $local_path = $file['local_path'];
152
  $remote_path = $file['remote_path'];
153
 
 
 
 
 
 
 
 
154
  if ( !file_exists( $local_path ) ) {
155
  $results[] = $this->_get_result( $local_path, $remote_path,
156
  W3TC_CDN_RESULT_ERROR, 'Source file not found.', $file );
145
  function upload( $files, &$results, $force_rewrite = false,
146
  $timeout_time = NULL ) {
147
  foreach ( $files as $file ) {
 
 
 
148
  $local_path = $file['local_path'];
149
  $remote_path = $file['remote_path'];
150
 
151
+ // process at least one item before timeout so that progress goes on
152
+ if ( !empty( $results ) ) {
153
+ if ( !is_null( $timeout_time ) && time() > $timeout_time ) {
154
+ return 'timeout';
155
+ }
156
+ }
157
+
158
  if ( !file_exists( $local_path ) ) {
159
  $results[] = $this->_get_result( $local_path, $remote_path,
160
  W3TC_CDN_RESULT_ERROR, 'Source file not found.', $file );
CdnEngine_S3.php CHANGED
@@ -30,6 +30,7 @@ class CdnEngine_S3 extends CdnEngine_Base {
30
  'key' => '',
31
  'secret' => '',
32
  'bucket' => '',
 
33
  'cname' => array(),
34
  ), $config );
35
 
@@ -83,7 +84,19 @@ class CdnEngine_S3 extends CdnEngine_Base {
83
  return false;
84
  }
85
 
86
- $this->_s3 = new \S3( $this->_config['key'], $this->_config['secret'], false );
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
  return true;
89
  }
@@ -107,12 +120,16 @@ class CdnEngine_S3 extends CdnEngine_Base {
107
  }
108
 
109
  foreach ( $files as $file ) {
110
- if ( !is_null( $timeout_time ) && time() > $timeout_time )
111
- break;
112
-
113
  $local_path = $file['local_path'];
114
  $remote_path = $file['remote_path'];
115
 
 
 
 
 
 
 
 
116
  $results[] = $this->_upload( $file, $force_rewrite );
117
 
118
  if ( $this->_config['compression'] && $this->_may_gzip( $remote_path ) ) {
@@ -167,10 +184,14 @@ class CdnEngine_S3 extends CdnEngine_Base {
167
  W3TC_CDN_RESULT_OK, 'OK', $file );
168
  }
169
 
 
 
 
 
 
 
170
  return $this->_get_result( $local_path, $remote_path,
171
- W3TC_CDN_RESULT_ERROR,
172
- sprintf( 'Unable to put object (%s).', $this->_get_last_error() ),
173
- $file );
174
  }
175
 
176
  /**
@@ -235,10 +256,14 @@ class CdnEngine_S3 extends CdnEngine_Base {
235
  W3TC_CDN_RESULT_OK, 'OK', $file );
236
  }
237
 
 
 
 
 
 
 
238
  return $this->_get_result( $local_path, $remote_path,
239
- W3TC_CDN_RESULT_ERROR,
240
- sprintf( 'Unable to put object (%s).', $this->_get_last_error() ),
241
- $file );
242
  }
243
 
244
  /**
@@ -337,7 +362,11 @@ class CdnEngine_S3 extends CdnEngine_Base {
337
  }
338
 
339
  if ( !@$this->_s3->putObjectString( $string, $this->_config['bucket'], $string, \S3::ACL_PUBLIC_READ ) ) {
340
- $error = sprintf( 'Unable to put object (%s).', $this->_get_last_error() );
 
 
 
 
341
 
342
  $this->_restore_error_handler();
343
 
30
  'key' => '',
31
  'secret' => '',
32
  'bucket' => '',
33
+ 'bucket_location' => '',
34
  'cname' => array(),
35
  ), $config );
36
 
84
  return false;
85
  }
86
 
87
+ if ( empty( $this->_config['bucket_location'] ) ) {
88
+ $region = '';
89
+ $endpoint = 's3.amazonaws.com';
90
+ } else {
91
+ $region = $this->_config['bucket_location'];
92
+ $endpoint = 's3.dualstack.' . $region . '.amazonaws.com';
93
+ }
94
+
95
+ $this->_s3 = new \S3( $this->_config['key'], $this->_config['secret'],
96
+ false, $endpoint, $region );
97
+ if ( empty( $region ) ) {
98
+ $this->_s3->setSignatureVersion( 'v2' );
99
+ }
100
 
101
  return true;
102
  }
120
  }
121
 
122
  foreach ( $files as $file ) {
 
 
 
123
  $local_path = $file['local_path'];
124
  $remote_path = $file['remote_path'];
125
 
126
+ // process at least one item before timeout so that progress goes on
127
+ if ( !empty( $results ) ) {
128
+ if ( !is_null( $timeout_time ) && time() > $timeout_time ) {
129
+ return 'timeout';
130
+ }
131
+ }
132
+
133
  $results[] = $this->_upload( $file, $force_rewrite );
134
 
135
  if ( $this->_config['compression'] && $this->_may_gzip( $remote_path ) ) {
184
  W3TC_CDN_RESULT_OK, 'OK', $file );
185
  }
186
 
187
+ if ( strpos( $this->_get_last_error(), 'AWS4-HMAC-SHA256' ) !== false ) {
188
+ $error = "Bucket location region is incorrect. Please select the right one.";
189
+ } else {
190
+ $error = sprintf( 'Unable to put object (%s).', $this->_get_last_error() );
191
+ }
192
+
193
  return $this->_get_result( $local_path, $remote_path,
194
+ W3TC_CDN_RESULT_ERROR, $error, $file );
 
 
195
  }
196
 
197
  /**
256
  W3TC_CDN_RESULT_OK, 'OK', $file );
257
  }
258
 
259
+ if ( strpos( $this->_get_last_error(), 'AWS4-HMAC-SHA256' ) !== false ) {
260
+ $error = "Bucket location region is incorrect. Please select the right one.";
261
+ } else {
262
+ $error = sprintf( 'Unable to put object (%s).', $this->_get_last_error() );
263
+ }
264
+
265
  return $this->_get_result( $local_path, $remote_path,
266
+ W3TC_CDN_RESULT_ERROR, $error, $file );
 
 
267
  }
268
 
269
  /**
362
  }
363
 
364
  if ( !@$this->_s3->putObjectString( $string, $this->_config['bucket'], $string, \S3::ACL_PUBLIC_READ ) ) {
365
+ if ( strpos( $this->_get_last_error(), 'AWS4-HMAC-SHA256' ) !== false ) {
366
+ $error = "Bucket location region is incorrect. Please select the right one.";
367
+ } else {
368
+ $error = sprintf( 'Unable to put object (%s).', $this->_get_last_error() );
369
+ }
370
 
371
  $this->_restore_error_handler();
372
 
CdnEngine_S3_Cf.php CHANGED
@@ -67,7 +67,20 @@ class CdnEngine_S3_Cf extends CdnEngine_S3 {
67
  return false;
68
  }
69
 
70
- $this->_s3 = new \S3( $this->_config['key'], $this->_config['secret'], false );
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
  return true;
73
  }
@@ -193,7 +206,7 @@ class CdnEngine_S3_Cf extends CdnEngine_S3 {
193
  }
194
 
195
  $this->_set_error_handler();
196
- $invalidation = @$this->_s3->createInvalidation( $dist['id'], $paths );
197
  $this->_restore_error_handler();
198
 
199
  if ( !$invalidation ) {
@@ -358,7 +371,7 @@ class CdnEngine_S3_Cf extends CdnEngine_S3 {
358
 
359
  $matches = null;
360
 
361
- if ( preg_match( '~^(.+)\.cloudfront\.net$~', $dist['domain'], $matches ) ) {
362
  $container_id = $matches[1];
363
  }
364
 
67
  return false;
68
  }
69
 
70
+ if ( empty( $this->_config['bucket_location'] ) ) {
71
+ $region = '';
72
+ $endpoint = 's3.amazonaws.com';
73
+ } else {
74
+ $region = $this->_config['bucket_location'];
75
+ $endpoint = 's3.dualstack.'.$region.'.amazonaws.com';
76
+ }
77
+
78
+ $this->_s3 = new \S3( $this->_config['key'], $this->_config['secret'],
79
+ false, $endpoint, $region );
80
+
81
+ if ( empty( $region ) ) {
82
+ $this->_s3->setSignatureVersion( 'v2' );
83
+ }
84
 
85
  return true;
86
  }
206
  }
207
 
208
  $this->_set_error_handler();
209
+ $invalidation = @$this->_s3->invalidateDistribution( $dist['id'], $paths );
210
  $this->_restore_error_handler();
211
 
212
  if ( !$invalidation ) {
371
 
372
  $matches = null;
373
 
374
+ if ( !empty( $dist['domain'] ) && preg_match( '~^(.+)\.cloudfront\.net$~', $dist['domain'], $matches ) ) {
375
  $container_id = $matches[1];
376
  }
377
 
CdnEngine_S3_Compatible.php CHANGED
@@ -33,6 +33,8 @@ class CdnEngine_S3_Compatible extends CdnEngine_Base {
33
 
34
  $this->_s3 = new \S3( $config['key'], $config['secret'], false,
35
  $config['api_host'] );
 
 
36
  parent::__construct( $config );
37
  }
38
 
@@ -72,12 +74,16 @@ class CdnEngine_S3_Compatible extends CdnEngine_Base {
72
  $error = null;
73
 
74
  foreach ( $files as $file ) {
75
- if ( !is_null( $timeout_time ) && time() > $timeout_time )
76
- break;
77
-
78
  $local_path = $file['local_path'];
79
  $remote_path = $file['remote_path'];
80
 
 
 
 
 
 
 
 
81
  $results[] = $this->_upload( $file, $force_rewrite );
82
 
83
  if ( $this->_config['compression'] && $this->_may_gzip( $remote_path ) ) {
33
 
34
  $this->_s3 = new \S3( $config['key'], $config['secret'], false,
35
  $config['api_host'] );
36
+ $this->_s3->setSignatureVersion( 'v2' );
37
+
38
  parent::__construct( $config );
39
  }
40
 
74
  $error = null;
75
 
76
  foreach ( $files as $file ) {
 
 
 
77
  $local_path = $file['local_path'];
78
  $remote_path = $file['remote_path'];
79
 
80
+ // process at least one item before timeout so that progress goes on
81
+ if ( !empty( $results ) ) {
82
+ if ( !is_null( $timeout_time ) && time() > $timeout_time ) {
83
+ return 'timeout';
84
+ }
85
+ }
86
+
87
  $results[] = $this->_upload( $file, $force_rewrite );
88
 
89
  if ( $this->_config['compression'] && $this->_may_gzip( $remote_path ) ) {
Cdn_AdminActions.php CHANGED
@@ -118,12 +118,12 @@ class Cdn_AdminActions {
118
  $results = array();
119
 
120
  $w3_plugin_cdn->export_library( $limit, $offset, $count, $total,
121
- $results, time() + 5 );
122
 
123
  $response = array(
124
  'limit' => $limit,
125
  'offset' => $offset,
126
- 'count' => count( $results ),
127
  'total' => $total,
128
  'results' => $results
129
  );
@@ -493,265 +493,26 @@ class Cdn_AdminActions {
493
  $type = Util_Request::get_string( 'type', 's3' );
494
 
495
  $locations = array(
496
- '' => 'US (Default)',
497
- 'us-west-1' => __( 'US-West (Northern California)', 'w3-total-cache' ),
498
- 'EU' => 'Europe',
499
- 'ap-southeast-1' => __( 'AP-SouthEast (Singapore)', 'w3-total-cache' ),
 
 
 
 
 
 
 
 
 
 
500