W3 Total Cache - Version 0.7.5.2

Version Description

  • Minified files now (optionally) upload automatically according to update interval (expiry time)
  • Provided memcache.ini directives updated to improve network throughput
  • Addressed WordPress MU site-wide activation/deactivation issues
  • Added empty (memcached) cache button to each tab
  • Fixed bug with parsing memcached server strings
  • Added warning dialog to minify tab about removal of query strings locally hosted object URIs
  • Fixed bug with minify sometimes not creating files as it should
  • Changed directory of minify working files to wp-content/w3tc-cache/
  • Improved reliability of memcache flush
Download this release

Release Info

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

Code changes from version 0.7.5.1 to 0.7.5.2

inc/define.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- define('W3TC_VERSION', '0.7.5.1');
4
  define('W3TC_POWERED_BY', 'W3 Total Cache/' . W3TC_VERSION);
5
  define('W3TC_LINK_URL', 'http://www.w3-edge.com/wordpress-plugins/');
6
  define('W3TC_LINK_NAME', 'WordPress Plugins');
@@ -292,16 +292,40 @@ function w3_upload_info()
292
  */
293
  function w3_redirect($url = '', $params = '')
294
  {
295
- $url = (! empty($url) ? $url : $_SERVER['HTTP_REFERER']);
296
- if (empty($url)) {
297
- $url = $_SERVER['REQUEST_URI'];
 
 
 
 
 
 
 
 
298
  }
299
 
 
300
  if (! empty($params)) {
301
- $params = (strpos($url, '?') === false ? '?' : '&') . $params;
302
- $url .= $params;
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  }
304
 
 
 
305
  header('Location: ' . $url);
306
  exit();
307
  }
1
  <?php
2
 
3
+ define('W3TC_VERSION', '0.7.5.2');
4
  define('W3TC_POWERED_BY', 'W3 Total Cache/' . W3TC_VERSION);
5
  define('W3TC_LINK_URL', 'http://www.w3-edge.com/wordpress-plugins/');
6
  define('W3TC_LINK_NAME', 'WordPress Plugins');
292
  */
293
  function w3_redirect($url = '', $params = '')
294
  {
295
+ $url = (! empty($url) ? $url : (! empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $_SERVER['REQUEST_URI']));
296
+
297
+ if (($parse_url = @parse_url($url))) {
298
+ $url = $parse_url['scheme'] . '://' . (! empty($parse_url['user']) ? $parse_url['user'] . (! empty($parse_url['pass']) ? ':' . $parse_url['pass'] : '') . '@' : '') . $parse_url['host'] . (! empty($parse_url['port']) ? ':' . $parse_url['port'] : '') . $parse_url['path'];
299
+ } else {
300
+ $parse_url = array();
301
+ }
302
+
303
+ $old_params = array();
304
+ if (! empty($parse_url['query'])) {
305
+ parse_str($parse_url['query'], $old_params);
306
  }
307
 
308
+ $new_params = array();
309
  if (! empty($params)) {
310
+ parse_str($params, $new_params);
311
+ }
312
+
313
+ $merged_params = array_merge($old_params, $new_params);
314
+
315
+ if (! empty($merged_params)) {
316
+ $count = count($merged_params);
317
+ $query_string = '';
318
+
319
+ foreach ($merged_params as $param => $value) {
320
+ $count --;
321
+ $query_string .= urlencode($param) . (! empty($value) ? '=' . urlencode($value) : '') . ($count ? '&' : '');
322
+ }
323
+
324
+ $url .= (strpos($url, '?') === false ? '?' : '&') . $query_string;
325
  }
326
 
327
+ $url .= (! empty($parse_url['fragment']) ? '#' . $parse_url['fragment'] : '');
328
+
329
  header('Location: ' . $url);
330
  exit();
331
  }
inc/js/options.js CHANGED
@@ -159,7 +159,7 @@ jQuery(function($) {
159
  });
160
 
161
  $('#minify_form').submit(function() {
162
- var js = [], css = [], invalid_js = [], invalid_css = [], duplicate = false;
163
 
164
  $('#js_files :text').each(function() {
165
  var v = $(this).val();
@@ -170,7 +170,17 @@ jQuery(function($) {
170
  break;
171
  }
172
  }
173
- js[js.length] = v;
 
 
 
 
 
 
 
 
 
 
174
  if (! /\.js$/.test(v)) {
175
  invalid_js.push(v);
176
  }
@@ -185,19 +195,43 @@ jQuery(function($) {
185
  break;
186
  }
187
  }
188
- css[css.length] = v;
 
 
 
 
 
 
 
 
 
 
189
  if (! /\.css$/.test(v)) {
190
  invalid_css.push(v);
191
  }
192
  }
193
  });
194
 
195
- if ($('#js_enabled:checked').size() && invalid_js.length && ! confirm('These files have invalid JS file extension:\r\n\r\n' + invalid_js.join('\r\n') + '\r\n\r\nAre you confident this files contain valid JS code?')) {
196
- return false;
 
 
 
 
 
 
 
197
  }
198
 
199
- if ($('#css_enabled:checked').size() && invalid_css.length && ! confirm('These files have invalid CSS file extension:\r\n\r\n' + invalid_css.join('\r\n') + '\r\n\r\nAre you confident this files contain valid CSS code?')) {
200
- return false;
 
 
 
 
 
 
 
201
  }
202
 
203
  if (duplicate) {
@@ -262,4 +296,13 @@ jQuery(function($) {
262
  status.html(data.error);
263
  }, 'json');
264
  });
 
 
 
 
 
 
 
 
 
265
  });
159
  });
160
 
161
  $('#minify_form').submit(function() {
162
+ var js = [], css = [], invalid_js = [], invalid_css = [], duplicate = false, query_js = [], query_css = [];
163
 
164
  $('#js_files :text').each(function() {
165
  var v = $(this).val();
170
  break;
171
  }
172
  }
173
+
174
+ js.push(v);
175
+
176
+ var qindex = v.indexOf('?');
177
+ if (qindex != -1) {
178
+ if (! /^https?:\/\//.test(v)) {
179
+ query_js.push(v);
180
+ }
181
+ v = v.substr(0, qindex);
182
+ }
183
+
184
  if (! /\.js$/.test(v)) {
185
  invalid_js.push(v);
186
  }
195
  break;
196
  }
197
  }
198
+
199
+ css.push(v);
200
+
201
+ var qindex = v.indexOf('?');
202
+ if (qindex != -1) {
203
+ if (! /^https?:\/\//.test(v)) {
204
+ query_css.push(v);
205
+ }
206
+ v = v.substr(0, qindex);
207
+ }
208
+
209
  if (! /\.css$/.test(v)) {
210
  invalid_css.push(v);
211
  }
212
  }
213
  });
214
 
215
+ if ($('#js_enabled:checked').size()) {
216
+ if (invalid_js.length && ! confirm('These files have invalid JS file extension:\r\n\r\n' + invalid_js.join('\r\n') + '\r\n\r\nAre you confident this files contain valid JS code?')) {
217
+ return false;
218
+ }
219
+
220
+ if (query_js.length) {
221
+ alert('These JS files contain query string in the name:\r\n\r\n' + query_js.join('\r\n'));
222
+ return false;
223
+ }
224
  }
225
 
226
+ if ($('#css_enabled:checked').size()) {
227
+ if (invalid_css.length && ! confirm('These files have invalid CSS file extension:\r\n\r\n' + invalid_css.join('\r\n') + '\r\n\r\nAre you confident this files contain valid CSS code?')) {
228
+ return false;
229
+ }
230
+
231
+ if (query_css.length) {
232
+ alert('These CSS files contain query string in the name:\r\n\r\n' + query_css.join('\r\n'));
233
+ return false;
234
+ }
235
  }
236
 
237
  if (duplicate) {
296
  status.html(data.error);
297
  }, 'json');
298
  });
299
+
300
+ var flush_types = ['flush_memcached_pgcache', 'flush_memcached_dbcache', 'flush_memcached_minify'];
301
+ for (var i = 0; i < flush_types.length; i++) {
302
+ $('#' + flush_types[i]).click(function(flush_type) {
303
+ return function() {
304
+ document.location.href = 'options-general.php?page=w3-total-cache/w3-total-cache.php&' + flush_type;
305
+ };
306
+ }(flush_types[i]));
307
+ }
308
  });
inc/options/cdn.phtml CHANGED
@@ -10,13 +10,6 @@
10
  </p>
11
 
12
  <form action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $tab; ?>" method="post">
13
-
14
- <!-- <p>
15
- <a href="#cdn_ftp" class="w3tc-tab" rel="#cdn_ftp"><acronym title="File Transfer Protocol">FTP</acronym> settings</a> |
16
- <a href="#cdn_cf" class="w3tc-tab" rel="#cdn_cf">Amazon CloudFront settings</a> |
17
- <a href="#cdn_s3" class="w3tc-tab" rel="#cdn_s3">Amazon S3 settings</a>
18
- </p> -->
19
-
20
  <div id="cdn_ftp" class="w3tc-tab-content">
21
  <table class="form-table">
22
  <tr>
@@ -54,19 +47,6 @@
54
  <input id="test_ftp" class="button" type="button" value="Test FTP server" /> <span id="test_ftp_status" class="w3tc-status w3tc-process"></span>
55
  </p>
56
  </div>
57
- <div id="cdn_cf" class="w3tc-tab-content" style="display: none;">
58
- to do...
59
- <p>
60
- <input class="button" type="button" value="Test CloudFront server" />
61
- </p>
62
- </div>
63
- <div id="cdn_s3" class="w3tc-tab-content" style="display: none;">
64
- to do...
65
- <p>
66
- <input class="button" type="button" value="Test S3 server" />
67
- </p>
68
- </div>
69
-
70
  <table class="form-table">
71
  <tr>
72
  <th style="width: 300px;"><label for="cdn_domain">Replace domain in <acronym title="Uniform Resource Locator">URL</acronym> with:</label></th>
10
  </p>
11
 
12
  <form action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $tab; ?>" method="post">
 
 
 
 
 
 
 
13
  <div id="cdn_ftp" class="w3tc-tab-content">
14
  <table class="form-table">
15
  <tr>
47
  <input id="test_ftp" class="button" type="button" value="Test FTP server" /> <span id="test_ftp_status" class="w3tc-status w3tc-process"></span>
48
  </p>
49
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  <table class="form-table">
51
  <tr>
52
  <th style="width: 300px;"><label for="cdn_domain">Replace domain in <acronym title="Uniform Resource Locator">URL</acronym> with:</label></th>
inc/options/dbcache.phtml CHANGED
@@ -7,8 +7,11 @@
7
  <tr>
8
  <th style="width: 250px;"><label for="memcached_servers">Memcached Hostname:Port / IP:Port:</label></th>
9
  <td>
10
- <input id="memcached_servers" type="text" name="dbcache.memcached.servers" value="<?php echo htmlspecialchars(implode(',', $config->get_array('dbcache.memcached.servers'))); ?>" size="100"<?php if ($config->get_string('dbcache.engine', 'memcached') != 'memcached'): ?> disabled="disabled"<?php endif; ?> /> <input id="test_memcached" class="button" type="button" value="Test Memcached"<?php if ($config->get_string('dbcache.engine', 'memcached') != 'memcached'): ?> disabled="disabled"<?php endif; ?> /> <span id="test_memcached_status" class="w3tc-status w3tc-process"></span><br />
11
- <span class="description">Multiple servers may be used and seperated by a comma; e.g. 192.168.1.100:11211, domain.com:22122</span>
 
 
 
12
  </td>
13
  </tr>
14
  <tr>
7
  <tr>
8
  <th style="width: 250px;"><label for="memcached_servers">Memcached Hostname:Port / IP:Port:</label></th>
9
  <td>
10
+ <input id="memcached_servers" type="text" name="dbcache.memcached.servers" value="<?php echo htmlspecialchars(implode(',', $config->get_array('dbcache.memcached.servers'))); ?>" size="100"<?php if (! $dbcache_memcached): ?> disabled="disabled"<?php endif; ?> />
11
+ <span id="test_memcached_status" class="w3tc-status w3tc-process"></span>
12
+ <input id="test_memcached" class="button" type="button" value="Test"<?php if (! $dbcache_memcached): ?> disabled="disabled"<?php endif; ?> />
13
+ <input id="flush_memcached_dbcache" class="button" type="button" value="Empty"<?php if (! $dbcache_memcached): ?> disabled="disabled"<?php endif; ?> />
14
+ <br /><span class="description">Multiple servers may be used and seperated by a comma; e.g. 192.168.1.100:11211, domain.com:22122</span>
15
  </td>
16
  </tr>
17
  <tr>
inc/options/faq.phtml CHANGED
@@ -77,7 +77,7 @@
77
  <li><a href="#q63">How can I serve my favicon from the <acronym title="Content Delivery Network">CDN</acronym>?</a></li>
78
  <li><a href="#q64">Why do you set the value of the media attribute of &lt;link&gt; to all?</a></li>
79
  <li><a href="#q65">Why can't I specify other &lt;script&gt; types or encoding?</a></li>
80
- <li><a href="#q66">My theme doesn't call wp_head() or wp_footer(), how do I set this plugin up?</a></li>
81
  <li><a href="#q67">Is this plugin compatible with other popular caching plugins?</a></li>
82
  <li><a href="#q68">Some WordPress caching plugins fail when markup is not well-formed, is this plugin similar?</a></li>
83
  <li><a href="#q69">Won't various 3rd parties who's <acronym title="JavaScript">JS</acronym> I download and cache be concerned?</a></li>
@@ -371,13 +371,15 @@ No, you can drag and drop them into the desired order on the minify settings pag
371
  <p id="q65"><strong>Why can't I specify other &lt;script&gt; types or encoding?</strong><br />
372
  We have not found a use case where this appears to be of any consequence. If you're aware of one <a href="mailto:wordpressexperts@w3-edge.com">please let us know</a>.</p>
373
  <p align="right"><a href="#toc">back to top</a></p>
374
- <p id="q66"><strong>My theme doesn't call wp_head() or wp_footer(), how do I set this plugin up?</strong><br />
375
  The calls you'll want to make for the various cases are:</p>
376
  <ul>
377
- <li>&lt;?php w3tc_scripts('include-footer'); ?&gt;<br />
378
  Inserts the footer <acronym title="JavaScript">JS</acronym> group at the location you specify in your theme.</li>
379
- <li>&lt;?php w3tc_scripts('include-footer_nb'); ?&gt;<br />
380
  Inserts the footer non-blocking <acronym title="JavaScript">JS</acronym> group at the location you specify in your theme.</li>
 
 
381
  </ul>
382
  <p align="right"><a href="#toc">back to top</a></p>
383
  <p id="q67"><strong>Is this plugin compatible with other popular caching plugins?</strong><br />
@@ -405,14 +407,15 @@ No, you can drag and drop them into the desired order on the minify settings pag
405
  Yes, any <acronym title="Cascading Style Sheet">CSS</acronym> and <acronym title="JavaScript">JS</acronym> you manage with the plugin are minified before being uploaded to your <acronym title="Content Delivery Network">CDN</acronym>. You don't have to make any special changes to your theme. We encourage you to make sure that your provider supports <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compression as the benefit of having your static assets available from more than one <acronym title="Point of Presence">POP</acronym> alone is not enough.</p>
406
  <p align="right"><a href="#toc">back to top</a></p>
407
  <p id="q75"><strong>Who do you recommend as a <acronym title="Content Delivery Network">CDN</acronym> provider?</strong><br />
408
- That depends on how you use your blog and where most of your readers read your blog (regionally). Here's a shortlist:</p>
409
  <ul>
 
410
  <li><a href="http://www.simplecdn.com/" target="_blank">Simple<acronym title="Content Delivery Network">CDN</acronym></a></li>
 
411
  <li><a href="http://www.edgecast.com/" target="_blank">EdgeCast</a></li>
 
412
  <li><a href="http://www.limelightnetworks.com/" target="_blank">Limelight Networks</a></li>
413
- <li><a href="http://aws.amazon.com/s3/" target="_blank">Amazon S3</a> / <a href="http://aws.amazon.com/cloudfront/" target="_blank">Cloudfront</a></li>
414
  <li><a href="http://www.akamai.com/" target="_blank">Akamai</a></li>
415
- <li><a href="http://www.voxel.net/products-services/voxcast-cdn" target="_blank">Voxel</a></li>
416
  </ul>
417
  <p align="right"><a href="#toc">back to top</a></p>
418
  <p id="q76"><strong>Hang on, don't I need to modify my <acronym title="Cascading Style Sheet">CSS</acronym> files so they'll work on the <acronym title="Content Delivery Network">CDN</acronym>?</strong><br />
@@ -422,7 +425,7 @@ No, you can drag and drop them into the desired order on the minify settings pag
422
  Yes! Please <a href="mailto:wordpressexperts@w3-edge.com">reach out to us</a> and we'll get you acclimated so you can "set it and forget it."</p>
423
  <p align="right"><a href="#toc">back to top</a></p>
424
  <p id="q78"><strong>Which web servers do you support?</strong><br />
425
- We are aware of no incompatibilities with <a href="http://httpd.apache.org/" target="_blank">apache</a> 1.3+ or <a href="http://www.iis.net/" target="_blank">IIS</a> 5+. We are still testing <a href="http://nginx.net/" target="_blank">nginx</a>, <a href="http://litespeedtech.com/products/webserver/overview/" target="_blank">litespeed</a> and <a href="http://www.lighttpd.net/" target="_blank">lighttpd</a>. If you have thoughts or an opinion, we're <a href="mailto:wordpressexperts@w3-edge.com">interested in hearing</a>.</p>
426
  <p align="right"><a href="#toc">back to top</a></p>
427
  <p id="q79"><strong>Do I need to enable mod_gzip, mod_rewrite or install any <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compression software on my server?</strong><br />
428
  No, but we do find that it does help some rich internet applications to compress their AJAX responses, so you might look at it just for that case.</p>
77
  <li><a href="#q63">How can I serve my favicon from the <acronym title="Content Delivery Network">CDN</acronym>?</a></li>
78
  <li><a href="#q64">Why do you set the value of the media attribute of &lt;link&gt; to all?</a></li>
79
  <li><a href="#q65">Why can't I specify other &lt;script&gt; types or encoding?</a></li>
80
+ <li><a href="#q66">My theme doesn't call wp_footer(), how do I set this plugin up?</a></li>
81
  <li><a href="#q67">Is this plugin compatible with other popular caching plugins?</a></li>
82
  <li><a href="#q68">Some WordPress caching plugins fail when markup is not well-formed, is this plugin similar?</a></li>
83
  <li><a href="#q69">Won't various 3rd parties who's <acronym title="JavaScript">JS</acronym> I download and cache be concerned?</a></li>
371
  <p id="q65"><strong>Why can't I specify other &lt;script&gt; types or encoding?</strong><br />
372
  We have not found a use case where this appears to be of any consequence. If you're aware of one <a href="mailto:wordpressexperts@w3-edge.com">please let us know</a>.</p>
373
  <p align="right"><a href="#toc">back to top</a></p>
374
+ <p id="q66"><strong>My theme doesn't call wp_footer(), how do I set this plugin up?</strong><br />
375
  The calls you'll want to make for the various cases are:</p>
376
  <ul>
377
+ <li>&lt;?php if (function_exists('w3tc_scripts')){w3tc_scripts('include-footer');} ?&gt;<br />
378
  Inserts the footer <acronym title="JavaScript">JS</acronym> group at the location you specify in your theme.</li>
379
+ <li>&lt;?php if (function_exists('w3tc_scripts')){w3tc_scripts('include-footer_nb');} ?&gt;<br />
380
  Inserts the footer non-blocking <acronym title="JavaScript">JS</acronym> group at the location you specify in your theme.</li>
381
+ <li>&lt;?php if (function_exists('w3tc_scripts')){w3tc_scripts('include-footer');w3tc_scripts('include-footer-nb');} ?&gt;<br />
382
+ Inserts both of the above <acronym title="JavaScript">JS</acronym> groups at the location you specify in your theme.</li>
383
  </ul>
384
  <p align="right"><a href="#toc">back to top</a></p>
385
  <p id="q67"><strong>Is this plugin compatible with other popular caching plugins?</strong><br />
407
  Yes, any <acronym title="Cascading Style Sheet">CSS</acronym> and <acronym title="JavaScript">JS</acronym> you manage with the plugin are minified before being uploaded to your <acronym title="Content Delivery Network">CDN</acronym>. You don't have to make any special changes to your theme. We encourage you to make sure that your provider supports <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compression as the benefit of having your static assets available from more than one <acronym title="Point of Presence">POP</acronym> alone is not enough.</p>
408
  <p align="right"><a href="#toc">back to top</a></p>
409
  <p id="q75"><strong>Who do you recommend as a <acronym title="Content Delivery Network">CDN</acronym> provider?</strong><br />
410
+ That depends on how you use your blog and where most of your readers read your blog (regionally). Here's a short list:</p>
411
  <ul>
412
+ <li><a href="http://www.netdna.com/" target="_blank">NetDNA</a></li>
413
  <li><a href="http://www.simplecdn.com/" target="_blank">Simple<acronym title="Content Delivery Network">CDN</acronym></a></li>
414
+ <li><a href="http://aws.amazon.com/s3/" target="_blank">Amazon S3</a> / <a href="http://aws.amazon.com/cloudfront/" target="_blank">Cloudfront</a></li>
415
  <li><a href="http://www.edgecast.com/" target="_blank">EdgeCast</a></li>
416
+ <li><a href="http://www.voxel.net/products-services/voxcast-cdn" target="_blank">Voxel</a></li>
417
  <li><a href="http://www.limelightnetworks.com/" target="_blank">Limelight Networks</a></li>
 
418
  <li><a href="http://www.akamai.com/" target="_blank">Akamai</a></li>
 
419
  </ul>
420
  <p align="right"><a href="#toc">back to top</a></p>
421
  <p id="q76"><strong>Hang on, don't I need to modify my <acronym title="Cascading Style Sheet">CSS</acronym> files so they'll work on the <acronym title="Content Delivery Network">CDN</acronym>?</strong><br />
425
  Yes! Please <a href="mailto:wordpressexperts@w3-edge.com">reach out to us</a> and we'll get you acclimated so you can "set it and forget it."</p>
426
  <p align="right"><a href="#toc">back to top</a></p>
427
  <p id="q78"><strong>Which web servers do you support?</strong><br />
428
+ We are aware of no incompatibilities with <a href="http://httpd.apache.org/" target="_blank">apache</a> 1.3+, <a href="http://www.iis.net/" target="_blank">IIS</a> 5+ or <a href="http://litespeedtech.com/products/webserver/overview/" target="_blank">litespeed</a> 4.0.2+. If there's a web server you feel we should be actively testing (e.g. <a href="http://www.lighttpd.net/" target="_blank">lighttpd</a>), we're <a href="mailto:wordpressexperts@w3-edge.com">interested in hearing</a>.</p>
429
  <p align="right"><a href="#toc">back to top</a></p>
430
  <p id="q79"><strong>Do I need to enable mod_gzip, mod_rewrite or install any <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compression software on my server?</strong><br />
431
  No, but we do find that it does help some rich internet applications to compress their AJAX responses, so you might look at it just for that case.</p>
inc/options/general.phtml CHANGED
@@ -1,12 +1,6 @@
1
  <?php
2
 
3
- $enabled = ($config->get_boolean('dbcache.enabled') || $config->get_boolean('pgcache.enabled') || $config->get_boolean('minify.enabled') || $config->get_boolean('cdn.enabled'));
4
- $debug = ($config->get_boolean('dbcache.debug') || $config->get_boolean('pgcache.debug') || $config->get_boolean('minify.debug') || $config->get_boolean('cdn.debug'));
5
- $support_type = $config->get_string('common.support.type', 'footer');
6
-
7
- $can_empty_memcache = ($config->get_string('dbcache.engine') == 'memcached' || $config->get_string('pgcache.engine') == 'memcached' || $config->get_string('minify.engine') == 'memcached');
8
- $can_empty_apc = ($config->get_string('dbcache.engine') == 'apc' || $config->get_string('pgcache.engine') == 'apc' || $config->get_string('minify.engine') == 'apc');
9
- $can_empty_disk = ($config->get_string('minify.engine') == 'file');
10
 
11
  $memcache_engine = class_exists('Memcache') ? '(Memcache)' : '';
12
 
@@ -42,7 +36,7 @@ foreach ($link_categories as $link_category) {
42
  <th valign="top">Page Caching:</th>
43
  <td>
44
  <input type="hidden" name="pgcache.enabled" value="0" />
45
- <label><input class="enabled" type="checkbox" name="pgcache.enabled" value="1"<?php checked($config->get_boolean('pgcache.enabled'), true); ?> />&nbsp;<strong>Enable</strong></label><br />
46
  <span class="description">Caching pages will reduce the response time of and increase the concurrency potential of your web server.</span>
47
  </td>
48
  </tr>
@@ -62,7 +56,7 @@ foreach ($link_categories as $link_category) {
62
  <th valign="top">Minify:</th>
63
  <td>
64
  <input type="hidden" name="minify.enabled" value="0" />
65
- <label><input class="enabled" type="checkbox" name="minify.enabled" value="1"<?php checked($config->get_boolean('minify.enabled'), true); ?> />&nbsp;<strong>Enable</strong></label><br />
66
  <span class="description">Minification can decrease file size of <acronym title="Hypertext Markup Language">HTML</acronym>, <acronym title="Cascading Style Sheets">CSS</acronym> and <acronym title="JavaScript">JS</acronym> respectively by ~10% on average.</span>
67
  </td>
68
  </tr>
@@ -83,7 +77,7 @@ foreach ($link_categories as $link_category) {
83
  <th valign="top">Database Caching:</th>
84
  <td>
85
  <input type="hidden" name="dbcache.enabled" value="0" />
86
- <label><input class="enabled" type="checkbox" name="dbcache.enabled" value="1"<?php checked($config->get_boolean('dbcache.enabled'), true); ?> />&nbsp;<strong>Enable</strong></label><br />
87
  <span class="description">Caching database objects will increase the response time of your blog by at least an order of magnitude in most cases.</span>
88
  </td>
89
  </tr>
@@ -103,15 +97,13 @@ foreach ($link_categories as $link_category) {
103
  <th><acronym title="Content Delivery Network">CDN</acronym>:</th>
104
  <td>
105
  <input type="hidden" name="cdn.enabled" value="0" />
106
- <label><input class="enabled" type="checkbox" name="cdn.enabled" value="1"<?php checked($config->get_boolean('cdn.enabled'), true); ?> />&nbsp;<strong>Enable</strong></label><br />
107
  </td>
108
  </tr>
109
  <tr>
110
  <th><acronym title="Content Delivery Network">CDN</acronym> Type:</th>
111
  <td>
112
  <label><input type="radio" name="cdn.engine" value="ftp"<?php checked($config->get_string('cdn.engine'), 'ftp'); ?> /> <acronym title="File Transfer Protocol">FTP</acronym></label><br />
113
- <!--<label><input type="radio" name="cdn.engine" value="cf"<?php checked($config->get_string('cdn.engine'), 'cf'); ?> /> Amazon CloudFront</label><br />
114
- <label><input type="radio" name="cdn.engine" value="s3"<?php checked($config->get_string('cdn.engine'), 's3'); ?> /> Amazon S3</label><br />-->
115
  <span class="description">Select the <acronym title="Content Delivery Network">CDN</acronym> type you wish to use.</span>
116
  </td>
117
  </tr>
1
  <?php
2
 
3
+ $support_type = $config->get_string('common.support.type');
 
 
 
 
 
 
4
 
5
  $memcache_engine = class_exists('Memcache') ? '(Memcache)' : '';
6
 
36
  <th valign="top">Page Caching:</th>
37
  <td>
38
  <input type="hidden" name="pgcache.enabled" value="0" />
39
+ <label><input class="enabled" type="checkbox" name="pgcache.enabled" value="1"<?php checked($pgcache_enabled, true); ?> />&nbsp;<strong>Enable</strong></label><br />
40
  <span class="description">Caching pages will reduce the response time of and increase the concurrency potential of your web server.</span>
41
  </td>
42
  </tr>
56
  <th valign="top">Minify:</th>
57
  <td>
58
  <input type="hidden" name="minify.enabled" value="0" />
59
+ <label><input class="enabled" type="checkbox" name="minify.enabled" value="1"<?php checked($minify_enabled, true); ?> />&nbsp;<strong>Enable</strong></label><br />
60
  <span class="description">Minification can decrease file size of <acronym title="Hypertext Markup Language">HTML</acronym>, <acronym title="Cascading Style Sheets">CSS</acronym> and <acronym title="JavaScript">JS</acronym> respectively by ~10% on average.</span>
61
  </td>
62
  </tr>
77
  <th valign="top">Database Caching:</th>
78
  <td>
79
  <input type="hidden" name="dbcache.enabled" value="0" />
80
+ <label><input class="enabled" type="checkbox" name="dbcache.enabled" value="1"<?php checked($dbcache_enabled, true); ?> />&nbsp;<strong>Enable</strong></label><br />
81
  <span class="description">Caching database objects will increase the response time of your blog by at least an order of magnitude in most cases.</span>
82
  </td>
83
  </tr>
97
  <th><acronym title="Content Delivery Network">CDN</acronym>:</th>
98
  <td>
99
  <input type="hidden" name="cdn.enabled" value="0" />
100
+ <label><input class="enabled" type="checkbox" name="cdn.enabled" value="1"<?php checked($cdn_enabled, true); ?> />&nbsp;<strong>Enable</strong></label><br />
101
  </td>
102
  </tr>
103
  <tr>
104
  <th><acronym title="Content Delivery Network">CDN</acronym> Type:</th>
105
  <td>
106
  <label><input type="radio" name="cdn.engine" value="ftp"<?php checked($config->get_string('cdn.engine'), 'ftp'); ?> /> <acronym title="File Transfer Protocol">FTP</acronym></label><br />
 
 
107
  <span class="description">Select the <acronym title="Content Delivery Network">CDN</acronym> type you wish to use.</span>
108
  </td>
109
  </tr>
inc/options/install.phtml CHANGED
@@ -2,15 +2,12 @@
2
  <h3>Installation</h3>
3
 
4
  <ol>
5
- <li>Disable and remove any other caching plugin you may be using &mdash; most plugins have uninstall procedures you can follow. Make sure wp-content/ has 777 permissions (e.g.: # chmod 777 /var/www/vhosts/domain.com/httpdocs/wp-content/) before proceeding.</li>
6
- <li>Unzip and upload the plugin to your plugins directory (wp-content/plugins/) when done wp-content/plugins/w3-total-cache/ should exist. If you have WordPress <acronym title="Multi-User">MU</acronym> you will need to install this in wp-content/mu-plugins/w3-total-cache/.</li>
7
- <li>Locate and activate the plugin on the <a href="/wp-admin/plugins.php">Plugins</a> page. Set the permisions of wp-content back to 755 (e.g.: # chmod 755 /var/www/vhosts/domain.com/httpdocs/wp-content/) and click through to the <a href="/wp-admin/options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=general">General Settings</a> tab.</li>
8
- <li>Select your caching preferences for page, database and minify. If memcached is used this will require you to confirm or modify the default settings and add any additional memcached servers you wish to use. To utilize <a href="#APC"><acronym title="Alternative PHP Cache">APC</acronym></a> and <a href="#memcached">memcached</a> + <a href="#memcache">memcache</a> installation guides have been provided for those with virtual dedicated or dedicated servers. For those in shared hosting environments, contact your provider to see if either of these are supported.</li>
9
- <li>If you already have a content delivery network provider, proceed to the <a href="/wp-admin/options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=cdn"><acronym title="Content Delivery Network">CDN</acronym> Settings</a> tab and populate the fields and set your preferences. If you're not running a version of WordPress with the Media Library feature, use the Media Library Import Tool to migrate your post images etc to appropriate locations.<br />
10
- <br />
11
- If you do not have a <acronym title="Content Delivery Network">CDN</acronym> provider, you can create and use a subdomain instead, e.g. subdomain.domain.com to improve server response, pipelining performance and progressive render.</li>
12
- <li>On the <a href="/wp-admin/options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=minify">Minify Settings</a> tab all of the recommended settings are preset. Specify any <acronym title="Cascading Style Sheet">CSS</acronym> and <acronym title="JavaScript">JS</acronym> files in the respective sections, view your site's <acronym title="Hypertext Markup Language">HTML</acronym> source and search for .<acronym title="Cascading Style Sheet">css</acronym> and .<acronym title="JavaScript">js</acronym> files. In the case of <acronym title="JavaScript">JS</acronym> files you can determine the type and location of the embedding using the drop down menu. Avoid the inclusion of packed or obfuscated <acronym title="JavaScript">JS</acronym> files in this step.</li>
13
- <li>Enable the plugin on the <a href="/wp-admin/options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=general">General Settings</a> tab.</li>
14
  <li>You're done! Get back to blogging!</li>
15
  </ol>
16
  Check out the <acronym title="Frequently Asked Questions">FAQ</acronym> for more details on <a href="/wp-admin/options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=faq">usage</a>.
2
  <h3>Installation</h3>
3
 
4
  <ol>
5
+ <li>Disable and remove any other caching plugin you may be using &mdash; most plugins have uninstall procedures you can follow. Make sure wp-content/ has 777 permissions before proceeding, e.g.: # chmod 777 /var/www/vhosts/domain.com/httpdocs/wp-content/</li>
6
+ <li>Ensure that wp-config.php contains the statement below; if you previously used a caching plugin, this statement is likely to exist already: define('WP_CACHE', true);</li>
7
+ <li>Locate and activate the plugin on the <a href="/wp-admin/plugins.php">Plugins</a> page, then click the Settings link to proceed to the <a href="/wp-admin/options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=general">General Settings</a> tab. Set the permisions of wp-content back to 755, e.g.: `# chmod 755 /var/www/vhosts/domain.com/httpdocs/wp-content/.</li>
8
+ <li>Select your caching preferences for page, database and minify. If memcached is used this will require you to confirm or modify the default settings and add any additional memcached servers you wish to use. To utilize <a href="#APC"><acronym title="Alternative PHP Cache">APC</acronym></a> and <a href="#memcached">memcached</a> + <a href="#memcache">memcache</a> installation guides have been provided under the Installation tab. For those in shared hosting environments, contact your provider to see if either of these are supported.</li>
9
+ <li>If you already have a content delivery network provider, proceed to the <a href="/wp-admin/options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=cdn"><acronym title="Content Delivery Network">CDN</acronym> Settings</a> tab and populate the fields and set your preferences. If you're not running a version of WordPress with the Media Library feature, use the Media Library Import Tool to migrate your post images etc to appropriate locations. If you do not have a <acronym title="Content Delivery Network">CDN</acronym> provider, you can still improve your site's performance using this feature. Create and use a subdomain on your own server; e.g. static.domain.com and configure options on the <acronym title="Content Delivery Network">CDN</acronym> tab accordingly.</li>
10
+ <li>On the <a href="/wp-admin/options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=minify">Minify Settings</a> tab all of the recommended settings are preset. Specify any <acronym title="Cascading Style Sheet">CSS</acronym> and <acronym title="JavaScript">JS</acronym> files in the respective sections, view your site's <acronym title="Hypertext Markup Language">HTML</acronym> source and search for .<acronym title="Cascading Style Sheet">css</acronym> and .<acronym title="JavaScript">js</acronym> files. In the case of <acronym title="JavaScript">JS</acronym> files you can specify the type and location of the embedding using the drop down menu.</li>
 
 
 
11
  <li>You're done! Get back to blogging!</li>
12
  </ol>
13
  Check out the <acronym title="Frequently Asked Questions">FAQ</acronym> for more details on <a href="/wp-admin/options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=faq">usage</a>.
inc/options/minify.phtml CHANGED
@@ -34,8 +34,11 @@ foreach ($js_check_groups as $js_check_group) {
34
  <tr>
35
  <th style="width: 250px;"><label for="memcached_servers">Memcached Hostname:Port / IP:Port:</label></th>
36
  <td>
37
- <input id="memcached_servers" type="text" name="minify.memcached.servers" value="<?php echo htmlspecialchars(implode(',', $config->get_array('minify.memcached.servers'))); ?>" size="100"<?php if ($config->get_string('minify.engine', 'memcached') != 'memcached'): ?> disabled="disabled"<?php endif; ?> /> <input id="test_memcached" class="button" type="button" value="Test Memcached"<?php if ($config->get_string('minify.engine', 'memcached') != 'memcached'): ?> disabled="disabled"<?php endif; ?> /> <span id="test_memcached_status" class="w3tc-status w3tc-process"></span><br />
38
- <span class="description">Multiple servers may be used and seperated by a comma; e.g. 192.168.1.100:11211, domain.com:22122</span>
 
 
 
39
  </td>
40
  </tr>
41
  <tr>
@@ -59,6 +62,12 @@ foreach ($js_check_groups as $js_check_group) {
59
  <span class="description">If disabled, <acronym title="Cascading Style Sheets">CSS</acronym> and <acronym title="JavaScript">JS</acronym> embeddings will use of GET variables, enabling this option is recommended unless you really want to avoid the redirects.</span>
60
  </th>
61
  </tr>
 
 
 
 
 
 
62
  <tr>
63
  <th><label for="minify_lifetime">Update external files every:</label></th>
64
  <td><input id="minify_lifetime" type="text" name="minify.lifetime" value="<?php echo $config->get_integer('minify.lifetime'); ?>" size="8" /> seconds<br />
34
  <tr>
35
  <th style="width: 250px;"><label for="memcached_servers">Memcached Hostname:Port / IP:Port:</label></th>
36
  <td>
37
+ <input id="memcached_servers" type="text" name="minify.memcached.servers" value="<?php echo htmlspecialchars(implode(',', $config->get_array('minify.memcached.servers'))); ?>" size="100"<?php if (! $minify_memcached): ?> disabled="disabled"<?php endif; ?> />
38
+ <span id="test_memcached_status" class="w3tc-status w3tc-process"></span>
39
+ <input id="test_memcached" class="button" type="button" value="Test"<?php if (! $minify_memcached): ?> disabled="disabled"<?php endif; ?> />
40
+ <input id="flush_memcached_minify" class="button" type="button" value="Empty"<?php if (! $minify_memcached): ?> disabled="disabled"<?php endif; ?> />
41
+ <br /><span class="description">Multiple servers may be used and seperated by a comma; e.g. 192.168.1.100:11211, domain.com:22122</span>
42
  </td>
43
  </tr>
44
  <tr>
62
  <span class="description">If disabled, <acronym title="Cascading Style Sheets">CSS</acronym> and <acronym title="JavaScript">JS</acronym> embeddings will use of GET variables, enabling this option is recommended unless you really want to avoid the redirects.</span>
63
  </th>
64
  </tr>
65
+ <tr>
66
+ <th colspan="2">
67
+ <input type="hidden" name="minify.upload" value="0" />
68
+ <label><input type="checkbox" name="minify.upload" value="1"<?php checked($config->get_boolean('minify.upload'), true); ?> /> Automatically upload modified files</label>
69
+ </th>
70
+ </tr>
71
  <tr>
72
  <th><label for="minify_lifetime">Update external files every:</label></th>
73
  <td><input id="minify_lifetime" type="text" name="minify.lifetime" value="<?php echo $config->get_integer('minify.lifetime'); ?>" size="8" /> seconds<br />
inc/options/pgcache.phtml CHANGED
@@ -1,14 +1,17 @@
1
  <h3>Page Cache Settings</h3>
2
 
3
- <p>Page Caching is currently <span class="w3tc-<?php if ($config->get_boolean('pgcache.enabled')): ?>enabled">enabled<?php else: ?>disabled">disabled<?php endif; ?></span>.</p>
4
 
5
  <form action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $tab; ?>" method="post">
6
  <table class="form-table">
7
  <tr>
8
  <th style="width: 250px;"><label for="memcached_servers">Memcached Hostname:Port / IP:Port:</label></th>
9
  <td>
10
- <input id="memcached_servers" type="text" name="pgcache.memcached.servers" value="<?php echo htmlspecialchars(implode(',', $config->get_array('pgcache.memcached.servers'))); ?>" size="100"<?php if ($config->get_string('pgcache.engine', 'memcached') != 'memcached'): ?> disabled="disabled"<?php endif; ?> /> <input id="test_memcached" class="button" type="button" value="Test Memcached"<?php if ($config->get_string('pgcache.engine', 'memcached') != 'memcached'): ?> disabled="disabled"<?php endif; ?> /> <span id="test_memcached_status" class="w3tc-status w3tc-process"></span><br />
11
- <span class="description">Multiple servers may be used and seperated by a comma; e.g. 192.168.1.100:11211, domain.com:22122</span>
 
 
 
12
  </td>
13
  </tr>
14
  <tr>
1
  <h3>Page Cache Settings</h3>
2
 
3
+ <p>Page Caching is currently <span class="w3tc-<?php if ($pgcache_enabled): ?>enabled">enabled<?php else: ?>disabled">disabled<?php endif; ?></span>.</p>
4
 
5
  <form action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $tab; ?>" method="post">
6
  <table class="form-table">
7
  <tr>
8
  <th style="width: 250px;"><label for="memcached_servers">Memcached Hostname:Port / IP:Port:</label></th>
9
  <td>
10
+ <input id="memcached_servers" type="text" name="pgcache.memcached.servers" value="<?php echo htmlspecialchars(implode(',', $config->get_array('pgcache.memcached.servers'))); ?>" size="100"<?php if (! $pgcache_memcached): ?> disabled="disabled"<?php endif; ?> />
11
+ <span id="test_memcached_status" class="w3tc-status w3tc-process"></span>
12
+ <input id="test_memcached" class="button" type="button" value="Test"<?php if (! $pgcache_memcached): ?> disabled="disabled"<?php endif; ?> />
13
+ <input id="flush_memcached_pgcache" class="button" type="button" value="Empty"<?php if (! $pgcache_memcached): ?> disabled="disabled"<?php endif; ?> />
14
+ <br /><span class="description">Multiple servers may be used and seperated by a comma; e.g. 192.168.1.100:11211, domain.com:22122</span>
15
  </td>
16
  </tr>
17
  <tr>
ini/memcache.ini CHANGED
@@ -3,4 +3,5 @@
3
  extension=memcache.so
4
  memcache.allow_failover = 1
5
  memcache.redundancy = 1
6
- memcache.session_redundancy = 2
 
3
  extension=memcache.so
4
  memcache.allow_failover = 1
5
  memcache.redundancy = 1
6
+ memcache.session_redundancy = 2
7
+ memcache.chunk_size = 32768
ini/php.append.ini CHANGED
@@ -1,4 +1,4 @@
1
  ; Use memcache as a session handler
2
  session.save_handler = memcache
3
  ; Use a comma separated list of server urls to use for storage:
4
- session.save_path="udp://localhost:11211?persistent=1&weight=1&timeout=1&retry_interval=15"
1
  ; Use memcache as a session handler
2
  session.save_handler = memcache
3
  ; Use a comma separated list of server urls to use for storage:
4
+ session.save_path="tcp://localhost:11211?persistent=1&weight=1&timeout=1&retry_interval=15"
lib/Minify/Minify/Controller/MinApp.php CHANGED
@@ -56,10 +56,10 @@ class Minify_Controller_MinApp extends Minify_Controller_Base {
56
  if (0 === strpos($file, '//')) {
57
  $file = $_SERVER['DOCUMENT_ROOT'] . substr($file, 1);
58
  }
59
- $file = realpath($file);
60
- if (is_file($file)) {
61
  $sources[] = new Minify_Source(array(
62
- 'filepath' => $file
63
  ));
64
  } else {
65
  $this->log("The path \"{$file}\" could not be found (or was not a file)");
56
  if (0 === strpos($file, '//')) {
57
  $file = $_SERVER['DOCUMENT_ROOT'] . substr($file, 1);
58
  }
59
+ $realPath = realpath($file);
60
+ if (is_file($realPath)) {
61
  $sources[] = new Minify_Source(array(
62
+ 'filepath' => $realPath
63
  ));
64
  } else {
65
  $this->log("The path \"{$file}\" could not be found (or was not a file)");
lib/W3/Cache.php CHANGED
@@ -15,6 +15,10 @@ if (! defined('W3_CACHE_APC')) {
15
  define('W3_CACHE_APC', 'apc');
16
  }
17
 
 
 
 
 
18
  /**
19
  * Class W3_Cache
20
  */
@@ -31,26 +35,33 @@ class W3_Cache
31
  {
32
  static $instances = array();
33
 
34
- if (! isset($instances[$engine])) {
 
 
35
  switch ($engine) {
36
  case W3_CACHE_MEMCACHED:
37
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached.php';
38
- $instances[$engine] = W3_Cache_Memcached::instance($config['engine'], $config);
39
  break;
40
 
41
  case W3_CACHE_APC:
42
  require_once W3TC_LIB_W3_DIR . '/Cache/Apc.php';
43
- $instances[$engine] = & new W3_Cache_Apc();
 
 
 
 
 
44
  break;
45
 
46
  default:
47
  trigger_error('Incorrect cache engine', E_USER_WARNING);
48
  require_once W3TC_LIB_W3_DIR . '/Cache/Base.php';
49
- $instances[$engine] = & new W3_Cache_Base();
50
  break;
51
  }
52
  }
53
-
54
- return $instances[$engine];
55
  }
56
  }
15
  define('W3_CACHE_APC', 'apc');
16
  }
17
 
18
+ if (! defined('W3_CACHE_FILE')) {
19
+ define('W3_CACHE_FILE', 'file');
20
+ }
21
+
22
  /**
23
  * Class W3_Cache
24
  */
35
  {
36
  static $instances = array();
37
 
38
+ $instance_key = sprintf('%s_%s', $engine, md5(serialize($config)));
39
+
40
+ if (! isset($instances[$instance_key])) {
41
  switch ($engine) {
42
  case W3_CACHE_MEMCACHED:
43
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached.php';
44
+ $instances[$instance_key] = W3_Cache_Memcached::instance($config['engine'], $config);
45
  break;
46
 
47
  case W3_CACHE_APC:
48
  require_once W3TC_LIB_W3_DIR . '/Cache/Apc.php';
49
+ $instances[$instance_key] = & new W3_Cache_Apc();
50
+ break;
51
+
52
+ case W3_CACHE_FILE:
53
+ require_once W3TC_LIB_W3_DIR . '/Cache/File.php';
54
+ $instances[$instance_key] = & new W3_Cache_File();
55
  break;
56
 
57
  default:
58
  trigger_error('Incorrect cache engine', E_USER_WARNING);
59
  require_once W3TC_LIB_W3_DIR . '/Cache/Base.php';
60
+ $instances[$instance_key] = & new W3_Cache_Base();
61
  break;
62
  }
63
  }
64
+
65
+ return $instances[$instance_key];
66
  }
67
  }
lib/W3/Cache/Apc.php CHANGED
@@ -86,6 +86,6 @@ class W3_Cache_Apc extends W3_Cache_Base
86
  */
87
  function flush()
88
  {
89
- return apc_clear_cache();
90
  }
91
  }
86
  */
87
  function flush()
88
  {
89
+ return apc_clear_cache('user');
90
  }
91
  }
lib/W3/Cache/File.php ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (! defined('W3_CACHE_FILE_EXPIRE_MAX')) {
4
+ define('W3_CACHE_FILE_EXPIRE_MAX', 864000);
5
+ }
6
+
7
+ /**
8
+ * APC class
9
+ */
10
+ require_once W3TC_LIB_W3_DIR . '/Cache/Base.php';
11
+
12
+ /**
13
+ * Class W3_Cache_File
14
+ */
15
+ class W3_Cache_File extends W3_Cache_Base
16
+ {
17
+ /**
18
+ * Path to cache dir
19
+ *
20
+ * @var string
21
+ */
22
+ var $_cache_dir = '';
23
+
24
+ /**
25
+ * Current time
26
+ *
27
+ * @var integer
28
+ */
29
+ var $_time = 0;
30
+
31
+ /**
32
+ * PHP5 constructor
33
+ *
34
+ * @param array $config
35
+ */
36
+ function __construct($config)
37
+ {
38
+ $this->_cache_dir = isset($config['cache_dir']) ? trim($config['cache_dir']) : 'cache';
39
+ $this->_time = time();
40
+ }
41
+
42
+ /**
43
+ * PHP4 constructor
44
+ *
45
+ * @return W3_Cache_File
46
+ */
47
+ function W3_Cache_File()
48
+ {
49
+ $this->__construct($config);
50
+ }
51
+
52
+ /**
53
+ * Adds data
54
+ *
55
+ * @param string $key
56
+ * @param mixed $var
57
+ * @param integer $expire
58
+ * @return boolean
59
+ */
60
+ function add($key, $var, $expire = 0)
61
+ {
62
+ if ($this->get($key) === false) {
63
+ return $this->set($key, $var, $expire);
64
+ }
65
+
66
+ return false;
67
+ }
68
+
69
+ /**
70
+ * Sets data
71
+ *
72
+ * @param string $key
73
+ * @param mixed $var
74
+ * @param integer $expire
75
+ * @return boolean
76
+ */
77
+ function set($key, $var, $expire = 0)
78
+ {
79
+ $path = $this->_get_path($key);
80
+ if (($fp = @fopen($path, 'w'))) {
81
+ @fputs($fp, $expire);
82
+ @fputs($fp, @serialize($var));
83
+ @fclose($fp);
84
+ return true;
85
+ }
86
+ return false;
87
+ }
88
+
89
+ /**
90
+ * Returns data
91
+ *
92
+ * @param string $key
93
+ * @return mixed
94
+ */
95
+ function get($key)
96
+ {
97
+ $path = $this->_get_path($key);
98
+ if (is_readable($path) && ($ftime = @filectime($path)) && ($fp = @fopen($path, 'r')) && ($expirec = @fgetc($fp)) !== false) {
99
+ $expire = (integer) $expirec;
100
+ $expire = ($expire && $expire <= W3_CACHE_FILE_EXPIRE_MAX ? $expire : W3_CACHE_FILE_EXPIRE_MAX);
101
+ if (($ftime + $expire) <= $this->_time) {
102
+ $data = '';
103
+ while (! @feof($fp)) {
104
+ $data .= @fgets($fp, 4096);
105
+ }
106
+ @fclose($fp);
107
+ return @unserialize($data);
108
+ }
109
+ @fclose($fp);
110
+ }
111
+ return false;
112
+ }
113
+
114
+ /**
115
+ * Replaces data
116
+ *
117
+ * @param string $key
118
+ * @param mixed $var
119
+ * @param integer $expire
120
+ * @return boolean
121
+ */
122
+ function replace($key, $var, $expire = 0)
123
+ {
124
+ if ($this->get($key) !== false) {
125
+ return $this->set($key, $var, $expire);
126
+ }
127
+
128
+ return false;
129
+ }
130
+
131
+ /**
132
+ * Deletes data
133
+ *
134
+ * @param string $key
135
+ * @return boolean
136
+ */
137
+ function delete($key)
138
+ {
139
+ $path = $this->_get_path($key);
140
+ if (file_exists($path)) {
141
+ return @unlink($path);
142
+ }
143
+ return false;
144
+ }
145
+
146
+ /**
147
+ * Flushes all data
148
+ *
149
+ * @return boolean
150
+ */
151
+ function flush()
152
+ {
153
+ }
154
+
155
+ /**
156
+ * Returns file path for key
157
+ *
158
+ * @param string $key
159
+ * @return string
160
+ */
161
+ function _get_path($key)
162
+ {
163
+ $hash = md5($key);
164
+ $path = sprintf('%s/%s/%s/%s', $this->_cache_dir, substr($hash, 0, 2), substr($hash, 2, 2), substr($hash, 4, 28));
165
+ $dir = dirname($path);
166
+ if (! is_dir($dir)) {
167
+ w3_mkdir($dir);
168
+ }
169
+
170
+ return $path;
171
+ }
172
+ }
lib/W3/Cache/Memcached.php CHANGED
@@ -31,9 +31,11 @@ class W3_Cache_Memcached
31
  */
32
  function &instance($engine = W3_CACHE_MEMCACHED_AUTO, $config = array())
33
  {
34
- static $instance = null;
35
 
36
- if ($instance === null) {
 
 
37
  if ($engine == W3_CACHE_MEMCACHED_AUTO) {
38
  $engine = (class_exists('Memcache') ? W3_CACHE_MEMCACHED_NATIVE : W3_CACHE_MEMCACHED_CLIENT);
39
  }
@@ -41,24 +43,24 @@ class W3_Cache_Memcached
41
  switch ($engine) {
42
  case W3_CACHE_MEMCACHED_NATIVE:
43
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached/Native.php';
44
- $instance = & new W3_Cache_Memcached_Native($config);
45
  break;
46
 
47
  case W3_CACHE_MEMCACHED_CLIENT:
48
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached/Client.php';
49
- $instance = & new W3_Cache_Memcached_Client($config);
50
  break;
51
 
52
  default:
53
  trigger_error('Incorrect memcached engine', E_USER_WARNING);
54
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached/Base.php';
55
- $instance = & new W3_Cache_Memcached_Base();
56
  break;
57
  }
58
 
59
- $instance->connect();
60
  }
61
 
62
- return $instance;
63
  }
64
  }
31
  */
32
  function &instance($engine = W3_CACHE_MEMCACHED_AUTO, $config = array())
33
  {
34
+ static $instances = array();
35
 
36
+ $instance_key = sprintf('%s_%s', $engine, md5(serialize($config)));
37
+
38
+ if (! isset($instances[$instance_key])) {
39
  if ($engine == W3_CACHE_MEMCACHED_AUTO) {
40
  $engine = (class_exists('Memcache') ? W3_CACHE_MEMCACHED_NATIVE : W3_CACHE_MEMCACHED_CLIENT);
41
  }
43
  switch ($engine) {
44
  case W3_CACHE_MEMCACHED_NATIVE:
45
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached/Native.php';
46
+ $instances[$instance_key] = & new W3_Cache_Memcached_Native($config);
47
  break;
48
 
49
  case W3_CACHE_MEMCACHED_CLIENT:
50
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached/Client.php';
51
+ $instances[$instance_key] = & new W3_Cache_Memcached_Client($config);
52
  break;
53
 
54
  default:
55
  trigger_error('Incorrect memcached engine', E_USER_WARNING);
56
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached/Base.php';
57
+ $instances[$instance_key] = & new W3_Cache_Memcached_Base();
58
  break;
59
  }
60
 
61
+ $instances[$instance_key]->connect();
62
  }
63
 
64
+ return $instances[$instance_key];
65
  }
66
  }
lib/W3/Cache/Memcached/Client.php CHANGED
@@ -29,8 +29,15 @@ class W3_Cache_Memcached_Client extends W3_Cache_Memcached_Base
29
  return false;
30
  }
31
 
 
 
 
 
 
 
 
32
  $this->_memcached = & new memcached_client(array(
33
- 'servers' => $this->config['servers'],
34
  'persistant' => isset($this->config['persistant']) ? (boolean) $this->config['persistant'] : false,
35
  'debug' => false,
36
  'compress_threshold' => (! empty($this->config['compress_threshold']) ? (integer) $this->config['compress_threshold'] : 0)
29
  return false;
30
  }
31
 
32
+ $servers = array();
33
+
34
+ foreach ($this->config['servers'] as $server) {
35
+ list ($host, $port) = explode(':', $server);
36
+ $servers[] = sprintf('%s:%d', trim($host), trim($port));
37
+ }
38
+
39
  $this->_memcached = & new memcached_client(array(
40
+ 'servers' => $servers,
41
  'persistant' => isset($this->config['persistant']) ? (boolean) $this->config['persistant'] : false,
42
  'debug' => false,
43
  'compress_threshold' => (! empty($this->config['compress_threshold']) ? (integer) $this->config['compress_threshold'] : 0)
lib/W3/Cache/Memcached/Native.php CHANGED
@@ -49,7 +49,7 @@ class W3_Cache_Memcached_Native extends W3_Cache_Memcached_Base
49
 
50
  foreach ((array) $this->config['servers'] as $server) {
51
  list ($ip, $port) = explode(':', $server);
52
- $this->_memcache->addServer($ip, $port, $persistant);
53
  }
54
  } else {
55
  return false;
@@ -69,7 +69,7 @@ class W3_Cache_Memcached_Native extends W3_Cache_Memcached_Base
69
  */
70
  function disconnect()
71
  {
72
- return $this->_memcache->close();
73
  }
74
 
75
  /**
@@ -82,7 +82,7 @@ class W3_Cache_Memcached_Native extends W3_Cache_Memcached_Base
82
  */
83
  function add($key, $var, $expire = 0)
84
  {
85
- return $this->_memcache->add($key, $var, false, $expire);
86
  }
87
 
88
  /**
@@ -95,7 +95,7 @@ class W3_Cache_Memcached_Native extends W3_Cache_Memcached_Base
95
  */
96
  function set($key, $var, $expire = 0)
97
  {
98
- return $this->_memcache->set($key, $var, false, $expire);
99
  }
100
 
101
  /**
@@ -106,7 +106,7 @@ class W3_Cache_Memcached_Native extends W3_Cache_Memcached_Base
106
  */
107
  function get($key)
108
  {
109
- return $this->_memcache->get($key);
110
  }
111
 
112
  /**
@@ -119,7 +119,7 @@ class W3_Cache_Memcached_Native extends W3_Cache_Memcached_Base
119
  */
120
  function replace($key, $var, $expire = 0)
121
  {
122
- return $this->_memcache->replace($key, $var, false, $expire);
123
  }
124
 
125
  /**
@@ -130,7 +130,7 @@ class W3_Cache_Memcached_Native extends W3_Cache_Memcached_Base
130
  */
131
  function delete($key)
132
  {
133
- return $this->_memcache->delete($key);
134
  }
135
 
136
  /**
@@ -140,6 +140,6 @@ class W3_Cache_Memcached_Native extends W3_Cache_Memcached_Base
140
  */
141
  function flush()
142
  {
143
- return $this->_memcache->flush();
144
  }
145
  }
49
 
50
  foreach ((array) $this->config['servers'] as $server) {
51
  list ($ip, $port) = explode(':', $server);
52
+ $this->_memcache->addServer(trim($ip), (integer) trim($port), $persistant);
53
  }
54
  } else {
55
  return false;
69
  */
70
  function disconnect()
71
  {
72
+ return @$this->_memcache->close();
73
  }
74
 
75
  /**
82
  */
83
  function add($key, $var, $expire = 0)
84
  {
85
+ return @$this->_memcache->add($key, $var, false, $expire);
86
  }
87
 
88
  /**
95
  */
96
  function set($key, $var, $expire = 0)
97
  {
98
+ return @$this->_memcache->set($key, $var, false, $expire);
99
  }
100
 
101
  /**
106
  */
107
  function get($key)
108
  {
109
+ return @$this->_memcache->get($key);
110
  }
111
 
112
  /**
119
  */
120
  function replace($key, $var, $expire = 0)
121
  {
122
+ return @$this->_memcache->replace($key, $var, false, $expire);
123
  }
124
 
125
  /**
130
  */
131
  function delete($key)
132
  {
133
+ return @$this->_memcache->delete($key);
134
  }
135
 
136
  /**
140
  */
141
  function flush()
142
  {
143
+ return @$this->_memcache->flush();
144
  }
145
  }
lib/W3/Cdn.php CHANGED
@@ -32,31 +32,33 @@ class W3_Cdn
32
  {
33
  static $instances = array();
34
 
35
- if (! isset($instances[$engine])) {
 
 
36
  switch ($engine) {
37
  case W3_CDN_FTP:
38
  require_once W3TC_LIB_W3_DIR . '/Cdn/Ftp.php';
39
- $instances[$engine] = & new W3_Cdn_Ftp($config);
40
  break;
41
 
42
  case W3_CDN_CF:
43
  require_once W3TC_LIB_W3_DIR . '/Cdn/Cf.php';
44
- $instances[$engine] = & new W3_Cdn_Cf($config);
45
  break;
46
 
47
  case W3_CDN_S3:
48
  require_once W3TC_LIB_W3_DIR . '/Cdn/S3.php';
49
- $instances[$engine] = & new W3_Cdn_S3($config);
50
  break;
51
 
52
  default:
53
  trigger_error('Incorrect CDN engine', E_USER_WARNING);
54
  require_once W3TC_LIB_W3_DIR . '/Cdn/Base.php';
55
- $instances[$engine] = & new W3_Cdn_Base();
56
  break;
57
  }
58
  }
59
 
60
- return $instances[$engine];
61
  }
62
  }
32
  {
33
  static $instances = array();
34
 
35
+ $instance_key = sprintf('%s_%s', $engine, md5(serialize($config)));
36
+
37
+ if (! isset($instances[$instance_key])) {
38
  switch ($engine) {
39
  case W3_CDN_FTP:
40
  require_once W3TC_LIB_W3_DIR . '/Cdn/Ftp.php';
41
+ $instances[$instance_key] = & new W3_Cdn_Ftp($config);
42
  break;
43
 
44
  case W3_CDN_CF:
45
  require_once W3TC_LIB_W3_DIR . '/Cdn/Cf.php';
46
+ $instances[$instance_key] = & new W3_Cdn_Cf($config);
47
  break;
48
 
49
  case W3_CDN_S3:
50
  require_once W3TC_LIB_W3_DIR . '/Cdn/S3.php';
51
+ $instances[$instance_key] = & new W3_Cdn_S3($config);
52
  break;
53
 
54
  default:
55
  trigger_error('Incorrect CDN engine', E_USER_WARNING);
56
  require_once W3TC_LIB_W3_DIR . '/Cdn/Base.php';
57
+ $instances[$instance_key] = & new W3_Cdn_Base();
58
  break;
59
  }
60
  }
61
 
62
+ return $instances[$instance_key];
63
  }
64
  }
lib/W3/Config.php CHANGED
@@ -66,7 +66,7 @@ class W3_Config
66
  'minify.memcached.engine' => 'string',
67
  'minify.memcached.servers' => 'array',
68
  'minify.rewrite' => 'boolean',
69
- 'minify.logger' => 'boolean',
70
  'minify.cache.path' => 'string',
71
  'minify.cache.locking' => 'string',
72
  'minify.docroot' => 'string',
@@ -76,6 +76,7 @@ class W3_Config
76
  'minify.options' => 'array',
77
  'minify.symlinks' => 'array',
78
  'minify.lifetime' => 'integer',
 
79
  'minify.html.enable' => 'boolean',
80
  'minify.html.strip.crlf' => 'boolean',
81
  'minify.html.reject.admin' => 'boolean',
@@ -114,9 +115,9 @@ class W3_Config
114
  'common.support.type' => 'string',
115
 
116
  'notes.defaults' => 'boolean',
117
- 'notes.wp_content_perms' => 'boolean',
118
- 'notes.cdn_first_time' => 'boolean',
119
- 'notes.no_memcached_nor_apc' => 'boolean',
120
  );
121
 
122
  /**
@@ -400,10 +401,13 @@ class W3_Config
400
  $instance = & new $class();
401
 
402
  if (! $instance->load_default()) {
 
 
403
  die(sprintf('<strong>W3 Total Cache Error:</strong> Unable to read default config file <strong>%s</strong> or it is broken. Please re-install plugin.', W3TC_CONFIG_DEFAULT_PATH));
404
  }
405
 
406
  if (! $instance->load() && $check_config) {
 
407
  die(sprintf('<strong>W3 Total Cache Error:</strong> Unable to read config file or it is broken. Please create <strong>%s</strong> from <strong>%s</strong>.', W3TC_CONFIG_PATH, W3TC_CONFIG_DEFAULT_PATH));
408
  }
409
  }
66
  'minify.memcached.engine' => 'string',
67
  'minify.memcached.servers' => 'array',
68
  'minify.rewrite' => 'boolean',
69
+ 'minify.logging' => 'boolean',
70
  'minify.cache.path' => 'string',
71
  'minify.cache.locking' => 'string',
72
  'minify.docroot' => 'string',
76
  'minify.options' => 'array',
77
  'minify.symlinks' => 'array',
78
  'minify.lifetime' => 'integer',
79
+ 'minify.upload' => 'boolean',
80
  'minify.html.enable' => 'boolean',
81
  'minify.html.strip.crlf' => 'boolean',
82
  'minify.html.reject.admin' => 'boolean',
115
  'common.support.type' => 'string',
116
 
117
  'notes.defaults' => 'boolean',
118
+ 'notes.wp_content_perms' => 'boolean',
119
+ 'notes.cdn_first_time' => 'boolean',
120
+ 'notes.no_memcached_nor_apc' => 'boolean'
121
  );
122
 
123
  /**
401
  $instance = & new $class();
402
 
403
  if (! $instance->load_default()) {
404
+ debug_print_backtrace();
405
+
406
  die(sprintf('<strong>W3 Total Cache Error:</strong> Unable to read default config file <strong>%s</strong> or it is broken. Please re-install plugin.', W3TC_CONFIG_DEFAULT_PATH));
407
  }
408
 
409
  if (! $instance->load() && $check_config) {
410
+ debug_print_backtrace();
411
  die(sprintf('<strong>W3 Total Cache Error:</strong> Unable to read config file or it is broken. Please create <strong>%s</strong> from <strong>%s</strong>.', W3TC_CONFIG_PATH, W3TC_CONFIG_DEFAULT_PATH));
412
  }
413
  }
lib/W3/Minify.php CHANGED
@@ -16,6 +16,13 @@ class W3_Minify
16
  */
17
  var $_config = null;
18
 
 
 
 
 
 
 
 
19
  /**
20
  * PHP5 constructor
21
  */
@@ -72,24 +79,13 @@ class W3_Minify
72
  $serve_options['debug'] = true;
73
  }
74
 
75
- if (($logger = $this->_config->get('minify.logger'))) {
76
  require_once W3TC_LIB_MINIFY_DIR . '/Minify/Logger.php';
77
- if (true === $logger) {
78
- require_once W3TC_LIB_MINIFY_DIR . '/FirePHP.php';
79
- Minify_Logger::setLogger(FirePHP::getInstance(true));
80
- } else {
81
- Minify_Logger::setLogger($logger);
82
- }
83
- }
84
-
85
- // check for URI versioning
86
- if (preg_match('/&\\d/', $_SERVER['QUERY_STRING'])) {
87
- $serve_options['maxAge'] = 31536000;
88
  }
89
 
90
  if (isset($_GET['f']) || (isset($_GET['g']) && isset($_GET['t']))) {
91
  if (isset($_GET['g']) && isset($_GET['t'])) {
92
- // will need groups config
93
  $serve_options['minApp']['groups'] = $this->_get_groups($_GET['t']);
94
 
95
  if ($_GET['t'] == 'js' && ((in_array($_GET['g'], array(
@@ -106,7 +102,6 @@ class W3_Minify
106
  }
107
  }
108
 
109
- // serve!
110
  @header('X-Powered-By: ' . W3TC_POWERED_BY);
111
  Minify::serve('MinApp', $serve_options);
112
  } else {
@@ -162,8 +157,10 @@ class W3_Minify
162
 
163
  $cache = $this->_get_cache();
164
 
165
- if (is_a($cache, 'Minify_Cache_Memcached') || is_a($cache, 'Minify_Cache_APC')) {
166
- return $cache->flush();
 
 
167
  } elseif (is_a($cache, 'Minify_Cache_File')) {
168
  if (! $cache_path) {
169
  $cache_path = $this->_config->get_string('minify.cache.path');
@@ -266,6 +263,23 @@ class W3_Minify
266
  return $source;
267
  }
268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  /**
270
  * Returns minify groups
271
  *
@@ -326,18 +340,27 @@ class W3_Minify
326
  }
327
  }
328
 
 
329
  $file_path = sprintf('%s/minify_%s.%s', $cache_path, md5($file), $type);
330
  $file_exists = file_exists($file_path);
331
 
332
- if ($file_exists && filemtime($file_path) >= (time() - $this->_config->get_integer('minify.lifetime', 3600))) {
333
  return $file_path;
334
  }
335
 
336
- if (($file_data = file_get_contents($file)) && ($fp = fopen($file_path, 'w'))) {
337
- fputs($fp, $file_data);
338
- fclose($fp);
339
-
340
- return $file_path;
 
 
 
 
 
 
 
 
341
  }
342
 
343
  return ($file_exists ? $file_path : false);
@@ -357,11 +380,11 @@ class W3_Minify
357
  case 'memcached':
358
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached.php';
359
  require_once W3TC_LIB_MINIFY_DIR . '/Minify/Cache/Memcache.php';
360
- $memcached = & W3_Cache_Memcached::instance($this->_config->get_string('minify.memcached.engine', 'auto'), array(
361
  'servers' => $this->_config->get_array('minify.memcached.servers'),
362
  'persistant' => true
363
  ));
364
- $cache = & new Minify_Cache_Memcache($memcached);
365
  break;
366
 
367
  case 'apc':
@@ -371,7 +394,14 @@ class W3_Minify
371
 
372
  default:
373
  require_once W3TC_LIB_MINIFY_DIR . '/Minify/Cache/File.php';
374
- $cache = & new Minify_Cache_File($this->_config->get_string('minify.cache.path'), $this->_config->get_boolean('minify.cache.locking'));
 
 
 
 
 
 
 
375
  break;
376
  }
377
  }
16
  */
17
  var $_config = null;
18
 
19
+ /**
20
+ * Memcached object
21
+ *
22
+ * @var W3_Cache_Memcached
23
+ */
24
+ var $_memcached = null;
25
+
26
  /**
27
  * PHP5 constructor
28
  */
79
  $serve_options['debug'] = true;
80
  }
81
 
82
+ if ($this->_config->get('minify.logging', true)) {
83
  require_once W3TC_LIB_MINIFY_DIR . '/Minify/Logger.php';
84
+ Minify_Logger::setLogger($this);
 
 
 
 
 
 
 
 
 
 
85
  }
86
 
87
  if (isset($_GET['f']) || (isset($_GET['g']) && isset($_GET['t']))) {
88
  if (isset($_GET['g']) && isset($_GET['t'])) {
 
89
  $serve_options['minApp']['groups'] = $this->_get_groups($_GET['t']);
90
 
91
  if ($_GET['t'] == 'js' && ((in_array($_GET['g'], array(
102
  }
103
  }
104
 
 
105
  @header('X-Powered-By: ' . W3TC_POWERED_BY);
106
  Minify::serve('MinApp', $serve_options);
107
  } else {
157
 
158
  $cache = $this->_get_cache();
159
 
160
+ if (is_a($cache, 'Minify_Cache_Memcache') && is_a($this->_memcached, 'W3_Cache_Memcached_Base')) {
161
+ return $this->_memcached->flush();
162
+ } elseif (is_a($cache, 'Minify_Cache_APC') && function_exists('apc_clear_cache')) {
163
+ return apc_clear_cache('user');
164
  } elseif (is_a($cache, 'Minify_Cache_File')) {
165
  if (! $cache_path) {
166
  $cache_path = $this->_config->get_string('minify.cache.path');
263
  return $source;
264
  }
265
 
266
+ /**
267
+ * Log
268
+ *
269
+ * @param mixed $object
270
+ * @param string $label
271
+ */
272
+ function log($object, $label = null)
273
+ {
274
+ $file = W3TC_MINIFY_DIR . '/error.log';
275
+ $data = sprintf("[%s] [%s] %s\n", date('r'), $_SERVER['REQUEST_URI'], $object);
276
+
277
+ if (($fp = @fopen($file, 'a'))) {
278
+ @fputs($fp, $data);
279
+ @fclose($fp);
280
+ }
281
+ }
282
+
283
  /**
284
  * Returns minify groups
285
  *
340
  }
341
  }
342
 
343
+ $lifetime = $this->_config->get_integer('minify.lifetime', 3600);
344
  $file_path = sprintf('%s/minify_%s.%s', $cache_path, md5($file), $type);
345
  $file_exists = file_exists($file_path);
346
 
347
+ if (file_exists($file_path) && @filemtime($file_path) >= (time() - $lifetime)) {
348
  return $file_path;
349
  }
350
 
351
+ if (is_dir($cache_path)) {
352
+ if (($file_data = @file_get_contents($file))) {
353
+ if (($fp = @fopen($file_path, 'w'))) {
354
+ @fputs($fp, $file_data);
355
+ @fclose($fp);
356
+ } else {
357
+ $this->log(sprintf('Unable to open file %s for writing', $file_path));
358
+ }
359
+ } else {
360
+ $this->log(sprintf('Unable to download URL: %s', $file));
361
+ }
362
+ } else {
363
+ $this->log(sprintf('Cache directory %s is not exists', $cache_path));
364
  }
365
 
366
  return ($file_exists ? $file_path : false);
380
  case 'memcached':
381
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached.php';
382
  require_once W3TC_LIB_MINIFY_DIR . '/Minify/Cache/Memcache.php';
383
+ $this->_memcached = & W3_Cache_Memcached::instance($this->_config->get_string('minify.memcached.engine', 'auto'), array(
384
  'servers' => $this->_config->get_array('minify.memcached.servers'),
385
  'persistant' => true
386
  ));
387
+ $cache = & new Minify_Cache_Memcache($this->_memcached);
388
  break;
389
 
390
  case 'apc':
394
 
395
  default:
396
  require_once W3TC_LIB_MINIFY_DIR . '/Minify/Cache/File.php';
397
+ $cache_path = $this->_config->get_string('minify.cache.path');
398
+ if (empty($cache_path)) {
399
+ $cache_path = W3TC_MINIFY_DIR;
400
+ }
401
+ if (! is_dir($cache_path)) {
402
+ $this->log(sprintf('Cache directory %s is not exists', $cache_path));
403
+ }
404
+ $cache = & new Minify_Cache_File($cache_path, $this->_config->get_boolean('minify.cache.locking'));
405
  break;
406
  }
407
  }
lib/W3/PgCache.php CHANGED
@@ -160,9 +160,9 @@ class W3_PgCache
160
  case 'deflate':
161
  return gzdeflate($buffer);
162
  }
163
- } else {
164
- return $buffer;
165
  }
 
 
166
  }
167
 
168
  /**
@@ -680,13 +680,6 @@ class W3_PgCache
680
  list ($header_name, $header_value) = explode(': ', $header, 2);
681
  $headers[$header_name] = $header_value;
682
  }
683
- } else {
684
- foreach (array_keys($_SERVER) as $skey) {
685
- if (substr($skey, 0, 5) == 'HTTP_') {
686
- $header_name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($skey, 5)))));
687
- $headers[$header_name] = $_SERVER[$skey];
688
- }
689
- }
690
  }
691
 
692
  return $headers;
160
  case 'deflate':
161
  return gzdeflate($buffer);
162
  }
 
 
163
  }
164
+
165
+ return $buffer;
166
  }
167
 
168
  /**
680
  list ($header_name, $header_value) = explode(': ', $header, 2);
681
  $headers[$header_name] = $header_value;
682
  }
 
 
 
 
 
 
 
683
  }
684
 
685
  return $headers;
lib/W3/Plugin/Minify.php CHANGED
@@ -104,6 +104,17 @@ class W3_Plugin_Minify extends W3_Plugin
104
  @unlink(W3TC_MINIFY_DIR . '/include-footer.js');
105
  @unlink(W3TC_MINIFY_DIR . '/include-footer-nb.js');
106
 
 
 
 
 
 
 
 
 
 
 
 
107
  @rmdir(W3TC_MINIFY_DIR);
108
  }
109
  }
104
  @unlink(W3TC_MINIFY_DIR . '/include-footer.js');
105
  @unlink(W3TC_MINIFY_DIR . '/include-footer-nb.js');
106
 
107
+ $dir = @dir(W3TC_MINIFY_DIR);
108
+ if ($dir) {
109
+ while (($entry = @$dir->read())) {
110
+ if (strpos($entry, 'minify_') === 0) {
111
+ @unlink(W3TC_MINIFY_DIR . DIRECTORY_SEPARATOR . $entry);
112
+ }
113
+ }
114
+ }
115
+
116
+ @unlink(W3TC_MINIFY_DIR . '/error.log');
117
+
118
  @rmdir(W3TC_MINIFY_DIR);
119
  }
120
  }
lib/W3/Plugin/TotalCache.php CHANGED
@@ -273,6 +273,21 @@ class W3_Plugin_TotalCache extends W3_Plugin
273
  if ($_SERVER['REQUEST_METHOD'] == 'POST') {
274
  $config->read_request();
275
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  if ($tab == 'minify') {
277
  $css_files_header = W3_Request::get_array('css_files_include');
278
  $js_files_header = W3_Request::get_array('js_files_include');
@@ -342,15 +357,9 @@ class W3_Plugin_TotalCache extends W3_Plugin
342
  ));
343
  }
344
 
345
- if ($tab == 'general') {
346
- $debug = W3_Request::get_boolean('debug');
347
-
348
- $config->set('dbcache.debug', $debug);
349
- $config->set('pgcache.debug', $debug);
350
- $config->set('minify.debug', $debug);
351
- $config->set('cdn.debug', $debug);
352
- }
353
-
354
  if ($config->save()) {
355
  $this->link_delete();
356
 
@@ -358,17 +367,49 @@ class W3_Plugin_TotalCache extends W3_Plugin
358
  $this->link_insert($link_category_id);
359
  }
360
 
 
 
 
 
361
  w3_redirect('', 'w3tc_notice_id=5');
362
  } else {
363
  w3_redirect('', 'w3tc_error_id=1');
364
  }
365
  }
366
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367
  /**
368
  * Flush all caches
369
  */
370
  if (isset($_REQUEST['flush_all'])) {
371
- $this->flush_all();
 
 
 
 
 
 
 
 
 
372
  w3_redirect('', 'w3tc_notice_id=1');
373
  }
374
 
@@ -376,7 +417,43 @@ class W3_Plugin_TotalCache extends W3_Plugin
376
  * Flush memcached cache
377
  */
378
  if (isset($_REQUEST['flush_memcached'])) {
379
- $this->flush_memcached();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
380
  w3_redirect('', 'w3tc_notice_id=2');
381
  }
382
 
@@ -384,7 +461,10 @@ class W3_Plugin_TotalCache extends W3_Plugin
384
  * Flush APC cache
385
  */
386
  if (isset($_REQUEST['flush_apc'])) {
387
- $this->flush_apc();
 
 
 
388
  w3_redirect('', 'w3tc_notice_id=3');
389
  }
390
 
@@ -392,7 +472,10 @@ class W3_Plugin_TotalCache extends W3_Plugin
392
  * Flish disk cache
393
  */
394
  if (isset($_REQUEST['flush_file'])) {
395
- $this->flush_file();
 
 
 
396
  w3_redirect('', 'w3tc_notice_id=4');
397
  }
398
 
@@ -409,14 +492,14 @@ class W3_Plugin_TotalCache extends W3_Plugin
409
  /**
410
  * Do some checks
411
  */
412
- if ($config->get_boolean('notes.defaults', true)) {
413
  $notes[] = 'The plugin is in quick setup mode, our recommended defaults are set. Simply satisfy all warnings and enable the plugin to get started or customize all of the settings you wish. <a href="options-general.php?page=' . W3TC_FILE . '&hide_note=defaults">Hide this message</a>';
414
  }
415
 
416
  /**
417
  * Check wp-content permissions
418
  */
419
- if ($config->get_boolean('notes.wp_content_perms', true)) {
420
  $wp_content_stat = stat(WP_CONTENT_DIR);
421
  $wp_content_mode = ($wp_content_stat['mode'] & 0777);
422
  if ($wp_content_mode != 0755) {
@@ -428,11 +511,11 @@ class W3_Plugin_TotalCache extends W3_Plugin
428
  * CDN checks
429
  */
430
  if ($tab == 'cdn') {
431
- if ($config->get('notes.cdn_first_time', true)) {
432
  $notes[] = 'It appears this is the first time you are using CDN feature. Unless you wish to first import attachments in your posts that are not already in the media library, please start a <strong>"manual export to <acronym title="Content Delivery Network">CDN</acronym>"</strong> and only enable this module after pending attachments have been successfully uploaded. <a href="options-general.php?page=' . W3TC_FILE . '&hide_note=cdn_first_time">Hide this message</a>';
433
  }
434
 
435
- if ($config->get('cdn.enabled') && $config->get('cdn.domain') == '') {
436
  $errors[] = 'The <strong>"Replace domain in URL with"</strong> field must be populated. Enter the hostname of your <acronym title="Content Delivery Network">CDN</acronym> provider. <em>This is the hostname you would enter into your address bar in order to view objects in your browser.</em>';
437
  }
438
  }
@@ -440,29 +523,39 @@ class W3_Plugin_TotalCache extends W3_Plugin
440
  /**
441
  * Check for memcached & APC
442
  */
443
- $check_memcache = $this->check_memcache();
444
- $check_apc = $this->check_apc();
445
-
446
- if (! $check_memcache && ! $check_apc && $config->get_boolean('notes.no_memcached_nor_apc', true)) {
447
  $notes[] = '<strong>Memcached</strong> nor <strong>APC</strong> appear to be installed correctly. <a href="options-general.php?page=' . W3TC_FILE . '&hide_note=no_memcached_nor_apc">Hide this message</a>';
448
  }
449
 
450
  /**
451
  * Check for PgCache availability
452
  */
453
- if ($config->get_boolean('pgcache.enabled')) {
454
  if (! $this->check_advanced_cache()) {
455
  $errors[] = '<strong>Page caching</strong> is not available. <strong>advanced-cache.php</strong> is not installed. Either the <strong>' . WP_CONTENT_DIR . '</strong> directory is not write-able or you have another caching plugin installed.';
456
  } elseif (! defined('WP_CACHE')) {
457
  $errors[] = '<strong>Page caching</strong> is not available. <strong>WP_CACHE</strong> constant is not defined in wp-config.php.';
 
 
458
  }
459
  }
460
 
461
  /**
462
  * Check for DbCache availability
463
  */
464
- if ($config->get_boolean('dbcache.enabled') && ! $this->check_db()) {
465
- $errors[] = '<strong>Database caching</strong> is not available. <strong>db.php</strong> is not installed. Either the <strong>' . WP_CONTENT_DIR . '</strong> directory is not write-able or you have another caching plugin installed.';
 
 
 
 
 
 
 
 
 
 
 
466
  }
467
 
468
  /**
@@ -704,6 +797,24 @@ class W3_Plugin_TotalCache extends W3_Plugin
704
  echo ']}';
705
  }
706
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
707
  /**
708
  * CDN Test FTP
709
  */
@@ -739,25 +850,45 @@ class W3_Plugin_TotalCache extends W3_Plugin
739
  echo sprintf('{result: %d, error: "%s"}', $result, addslashes($error));
740
  }
741
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
742
  /**
743
  * Test memcached
744
  */
745
  function test_memcached()
746
  {
747
  require_once W3TC_LIB_W3_DIR . '/Request.php';
748
- require_once W3TC_LIB_W3_DIR . '/Cache/Memcached.php';
749
 
750
  $servers = W3_Request::get_string('servers');
751
- $test_string = sprintf('test_' . md5(time()));
752
-
753
- $memcached = W3_Cache_Memcached::instance(W3_CACHE_MEMCACHED_AUTO, array(
754
- 'servers' => $servers,
755
- 'persistant' => false
756
- ));
757
-
758
- $memcached->set($test_string, $test_string);
759
 
760
- if ($memcached->get($test_string) == $test_string) {
761
  $result = true;
762
  $error = 'Test passed';
763
  } else {
@@ -829,18 +960,18 @@ class W3_Plugin_TotalCache extends W3_Plugin
829
  */
830
  function flush($type)
831
  {
832
- if ($this->_config->get_string('dbcache.engine') == $type) {
833
- require_once W3TC_DIR . '/lib/W3/Db.php';
834
- $w3_db = W3_Db::instance();
835
- $w3_db->flush();
836
- }
837
-
838
  if ($this->_config->get_string('pgcache.engine') == $type) {
839
  require_once W3TC_DIR . '/lib/W3/PgCache.php';
840
  $w3_pgcache = W3_PgCache::instance();
841
  $w3_pgcache->flush();
842
  }
843
 
 
 
 
 
 
 
844
  if ($this->_config->get_string('minify.engine') == $type) {
845
  require_once W3TC_DIR . '/lib/W3/Minify.php';
846
  $w3_minify = W3_Minify::instance();
@@ -848,38 +979,32 @@ class W3_Plugin_TotalCache extends W3_Plugin
848
  }
849
  }
850
 
851
- /**
852
- * Flush all caches
853
- */
854
- function flush_all()
855
- {
856
- $this->flush_memcached();
857
- $this->flush_apc();
858
- $this->flush_file();
859
- }
860
-
861
  /**
862
  * Flush memcached cache
 
 
863
  */
864
- function flush_memcached()
865
- {
866
- $this->flush('memcached');
867
- }
868
-
869
- /**
870
- * Flush APC cache
871
- */
872
- function flush_apc()
873
- {
874
- $this->flush('memcached');
875
- }
876
-
877
- /**
878
- * Flush file cache
879
- */
880
- function flush_file()
881
  {
882
- $this->flush('file');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
883
  }
884
 
885
  /**
273
  if ($_SERVER['REQUEST_METHOD'] == 'POST') {
274
  $config->read_request();
275
 
276
+ /**
277
+ * General tab
278
+ */
279
+ if ($tab == 'general') {
280
+ $debug = W3_Request::get_boolean('debug');
281
+
282
+ $config->set('dbcache.debug', $debug);
283
+ $config->set('pgcache.debug', $debug);
284
+ $config->set('minify.debug', $debug);
285
+ $config->set('cdn.debug', $debug);
286
+ }
287
+
288
+ /**
289
+ * Minify tab
290
+ */
291
  if ($tab == 'minify') {
292
  $css_files_header = W3_Request::get_array('css_files_include');
293
  $js_files_header = W3_Request::get_array('js_files_include');
357
  ));
358
  }
359
 
360
+ /**
361
+ * Save config
362
+ */
 
 
 
 
 
 
363
  if ($config->save()) {
364
  $this->link_delete();
365
 
367
  $this->link_insert($link_category_id);
368
  }
369
 
370
+ if ($tab == 'minify' && $config->get_boolean('minify.upload') && $config->get_boolean('cdn.enabled')) {
371
+ $this->cdn_upload_minify();
372
+ }
373
+
374
  w3_redirect('', 'w3tc_notice_id=5');
375
  } else {
376
  w3_redirect('', 'w3tc_error_id=1');
377
  }
378
  }
379
 
380
+ $pgcache_enabled = $config->get_boolean('pgcache.enabled');
381
+ $dbcache_enabled = $config->get_boolean('dbcache.enabled');
382
+ $minify_enabled = $config->get_boolean('minify.enabled');
383
+ $cdn_enabled = $config->get_boolean('cdn.enabled');
384
+
385
+ $enabled = ($pgcache_enabled || $dbcache_enabled || $minify_enabled || $cdn_enabled);
386
+ $debug = ($config->get_boolean('dbcache.debug') || $config->get_boolean('pgcache.debug') || $config->get_boolean('minify.debug') || $config->get_boolean('cdn.debug'));
387
+
388
+ $check_memcache = $this->check_memcache();
389
+ $check_apc = $this->check_apc();
390
+
391
+ $pgcache_memcached = ($config->get_string('pgcache.engine') == 'memcached');
392
+ $dbcache_memcached = ($config->get_string('dbcache.engine') == 'memcached');
393
+ $minify_memcached = ($config->get_string('minify.engine') == 'memcached');
394
+
395
+ $can_empty_memcache = ($pgcache_memcached || $dbcache_memcached || $minify_memcached);
396
+ $can_empty_apc = ($config->get_string('dbcache.engine') == 'apc' || $config->get_string('pgcache.engine') == 'apc' || $config->get_string('minify.engine') == 'apc');
397
+ $can_empty_disk = ($config->get_string('minify.engine') == 'file');
398
+
399
  /**
400
  * Flush all caches
401
  */
402
  if (isset($_REQUEST['flush_all'])) {
403
+ if ($can_empty_memcache) {
404
+ $this->flush('memcached');
405
+ }
406
+ if ($can_empty_apc) {
407
+ $this->flush('apc');
408
+ }
409
+ if ($can_empty_disk) {
410
+ $this->flush('file');
411
+ }
412
+
413
  w3_redirect('', 'w3tc_notice_id=1');
414
  }
415
 
417
  * Flush memcached cache
418
  */
419
  if (isset($_REQUEST['flush_memcached'])) {
420
+ if ($can_empty_memcache) {
421
+ $this->flush('memcached');
422
+ }
423
+
424
+ w3_redirect('', 'w3tc_notice_id=2');
425
+ }
426
+
427
+ /**
428
+ * Flush memcached cache
429
+ */
430
+ if (isset($_REQUEST['flush_memcached_pgcache'])) {
431
+ if ($can_empty_memcache) {
432
+ $this->flush_memcached('pgcache');
433
+ }
434
+
435
+ w3_redirect('', 'w3tc_notice_id=2');
436
+ }
437
+
438
+ /**
439
+ * Flush memcached cache
440
+ */
441
+ if (isset($_REQUEST['flush_memcached_dbcache'])) {
442
+ if ($can_empty_memcache) {
443
+ $this->flush_memcached('dbcache');
444
+ }
445
+
446
+ w3_redirect('', 'w3tc_notice_id=2');
447
+ }
448
+
449
+ /**
450
+ * Flush memcached cache
451
+ */
452
+ if (isset($_REQUEST['flush_memcached_minify'])) {
453
+ if ($can_empty_memcache) {
454
+ $this->flush_memcached('minify');
455
+ }
456
+
457
  w3_redirect('', 'w3tc_notice_id=2');
458
  }
459
 
461
  * Flush APC cache
462
  */
463
  if (isset($_REQUEST['flush_apc'])) {
464
+ if ($can_empty_apc) {
465
+ $this->flush('apc');
466
+ }
467
+
468
  w3_redirect('', 'w3tc_notice_id=3');
469
  }
470
 
472
  * Flish disk cache
473
  */
474
  if (isset($_REQUEST['flush_file'])) {
475
+ if ($can_empty_disk) {
476
+ $this->flush('file');
477
+ }
478
+
479
  w3_redirect('', 'w3tc_notice_id=4');
480
  }
481
 
492
  /**
493
  * Do some checks
494
  */
495
+ if ($config->get_boolean('notes.defaults')) {
496
  $notes[] = 'The plugin is in quick setup mode, our recommended defaults are set. Simply satisfy all warnings and enable the plugin to get started or customize all of the settings you wish. <a href="options-general.php?page=' . W3TC_FILE . '&hide_note=defaults">Hide this message</a>';
497
  }
498
 
499
  /**
500
  * Check wp-content permissions
501
  */
502
+ if ($config->get_boolean('notes.wp_content_perms')) {
503
  $wp_content_stat = stat(WP_CONTENT_DIR);
504
  $wp_content_mode = ($wp_content_stat['mode'] & 0777);
505
  if ($wp_content_mode != 0755) {
511
  * CDN checks
512
  */
513
  if ($tab == 'cdn') {
514
+ if ($config->get('notes.cdn_first_time')) {
515
  $notes[] = 'It appears this is the first time you are using CDN feature. Unless you wish to first import attachments in your posts that are not already in the media library, please start a <strong>"manual export to <acronym title="Content Delivery Network">CDN</acronym>"</strong> and only enable this module after pending attachments have been successfully uploaded. <a href="options-general.php?page=' . W3TC_FILE . '&hide_note=cdn_first_time">Hide this message</a>';
516
  }
517
 
518
+ if ($cdn_enabled && $config->get('cdn.domain') == '') {
519
  $errors[] = 'The <strong>"Replace domain in URL with"</strong> field must be populated. Enter the hostname of your <acronym title="Content Delivery Network">CDN</acronym> provider. <em>This is the hostname you would enter into your address bar in order to view objects in your browser.</em>';
520
  }
521
  }
523
  /**
524
  * Check for memcached & APC
525
  */
526
+ if (! $check_memcache && ! $check_apc && $config->get_boolean('notes.no_memcached_nor_apc')) {
 
 
 
527
  $notes[] = '<strong>Memcached</strong> nor <strong>APC</strong> appear to be installed correctly. <a href="options-general.php?page=' . W3TC_FILE . '&hide_note=no_memcached_nor_apc">Hide this message</a>';
528
  }
529
 
530
  /**
531
  * Check for PgCache availability
532
  */
533
+ if ($pgcache_enabled) {
534
  if (! $this->check_advanced_cache()) {
535
  $errors[] = '<strong>Page caching</strong> is not available. <strong>advanced-cache.php</strong> is not installed. Either the <strong>' . WP_CONTENT_DIR . '</strong> directory is not write-able or you have another caching plugin installed.';
536
  } elseif (! defined('WP_CACHE')) {
537
  $errors[] = '<strong>Page caching</strong> is not available. <strong>WP_CACHE</strong> constant is not defined in wp-config.php.';
538
+ } elseif ($pgcache_memcached && ! $this->is_memcache_available($config->get_array('pgcache.memcached.servers'))) {
539
+ $errors[] = sprintf('<strong>Page caching</strong> is not available. Memcached server <strong>%s</strong> is not running or is non-responsive.', implode(', ', $config->get_array('pgcache.memcached.servers')));
540
  }
541
  }
542
 
543
  /**
544
  * Check for DbCache availability
545
  */
546
+ if ($dbcache_enabled) {
547
+ if (! $this->check_db()) {
548
+ $errors[] = '<strong>Database caching</strong> is not available. <strong>db.php</strong> is not installed. Either the <strong>' . WP_CONTENT_DIR . '</strong> directory is not write-able or you have another caching plugin installed.';
549
+ } elseif ($dbcache_memcached && ! $this->is_memcache_available($config->get_array('dbcache.memcached.servers'))) {
550
+ $errors[] = sprintf('<strong>Database caching</strong> is not available. Memcached server <strong>%s</strong> is not running or is non-responsive.', implode(', ', $config->get_array('dbcache.memcached.servers')));
551
+ }
552
+ }
553
+
554
+ /**
555
+ * Check for minify availability
556
+ */
557
+ if ($minify_enabled && $minify_memcached && ! $this->is_memcache_available($config->get_array('minify.memcached.servers'))) {
558
+ $errors[] = sprintf('<strong>Minify</strong> is not available. Memcached server <strong>%s</strong> is not running or is non-responsive.', implode(', ', $config->get_array('minify.memcached.servers')));
559
  }
560
 
561
  /**
797
  echo ']}';
798
  }
799
 
800
+ /**
801
+ * Uploads minify files to CDN
802
+ */
803
+ function cdn_upload_minify()
804
+ {
805
+ require_once W3TC_LIB_W3_DIR . '/Plugin/Cdn.php';
806
+
807
+ $w3_plugin_cdn = W3_Plugin_Cdn::instance();
808
+ $files = $w3_plugin_cdn->get_files_minify();
809
+ $upload = array();
810
+
811
+ foreach ($files as $file) {
812
+ $upload[$file] = $file;
813
+ }
814
+
815
+ return @$w3_plugin_cdn->upload($upload);
816
+ }
817
+
818
  /**
819
  * CDN Test FTP
820
  */
850
  echo sprintf('{result: %d, error: "%s"}', $result, addslashes($error));
851
  }
852
 
853
+ /**
854
+ * Check if memcache is available
855
+ *
856
+ * @param array $servers
857
+ * @return boolean
858
+ */
859
+ function is_memcache_available($servers)
860
+ {
861
+ static $results = array();
862
+
863
+ $key = md5(serialize($servers));
864
+
865
+ if (! isset($results[$key])) {
866
+ require_once W3TC_LIB_W3_DIR . '/Cache/Memcached.php';
867
+
868
+ $memcached = W3_Cache_Memcached::instance(W3_CACHE_MEMCACHED_AUTO, array(
869
+ 'servers' => $servers,
870
+ 'persistant' => false
871
+ ));
872
+
873
+ $test_string = sprintf('test_' . md5(time()));
874
+ $memcached->set($test_string, $test_string, 60);
875
+
876
+ $results[$key] = ($memcached->get($test_string) == $test_string);
877
+ }
878
+
879
+ return $results[$key];
880
+ }
881
+
882
  /**
883
  * Test memcached
884
  */
885
  function test_memcached()
886
  {
887
  require_once W3TC_LIB_W3_DIR . '/Request.php';
 
888
 
889
  $servers = W3_Request::get_string('servers');
 
 
 
 
 
 
 
 
890
 
891
+ if ($this->is_memcache_available($servers)) {
892
  $result = true;
893
  $error = 'Test passed';
894
  } else {
960
  */
961
  function flush($type)
962
  {
 
 
 
 
 
 
963
  if ($this->_config->get_string('pgcache.engine') == $type) {
964
  require_once W3TC_DIR . '/lib/W3/PgCache.php';
965
  $w3_pgcache = W3_PgCache::instance();
966
  $w3_pgcache->flush();
967
  }
968
 
969
+ if ($this->_config->get_string('dbcache.engine') == $type) {
970
+ require_once W3TC_DIR . '/lib/W3/Db.php';
971
+ $w3_db = W3_Db::instance();
972
+ $w3_db->flush_cache();
973
+ }
974
+
975
  if ($this->_config->get_string('minify.engine') == $type) {
976
  require_once W3TC_DIR . '/lib/W3/Minify.php';
977
  $w3_minify = W3_Minify::instance();
979
  }
980
  }
981
 
 
 
 
 
 
 
 
 
 
 
982
  /**
983
  * Flush memcached cache
984
+ *
985
+ * @param string $type
986
  */
987
+ function flush_memcached($type)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
988
  {
989
+ switch (true) {
990
+ case ($type == 'pgcache' && $this->_config->get_string('pgcache.engine') == 'memcached'):
991
+ require_once W3TC_DIR . '/lib/W3/PgCache.php';
992
+ $w3_pgcache = W3_PgCache::instance();
993
+ $w3_pgcache->flush();
994
+ break;
995
+
996
+ case ($type == 'dbcache' && $this->_config->get_string('dbcache.engine') == 'memcached'):
997
+ require_once W3TC_DIR . '/lib/W3/Db.php';
998
+ $w3_db = W3_Db::instance();
999
+ $w3_db->flush_cache();
1000
+ break;
1001
+
1002
+ case ($type == 'minify' && $this->_config->get_string('minify.engine') == 'memcached'):
1003
+ require_once W3TC_DIR . '/lib/W3/Minify.php';
1004
+ $w3_minify = W3_Minify::instance();
1005
+ $w3_minify->flush();
1006
+ break;
1007
+ }
1008
  }
1009
 
1010
  /**
readme.txt CHANGED
@@ -3,13 +3,15 @@ Contributors: fredericktownes
3
  Tags: user experience, cache, caching, page cache, css cache, js cache, db cache, database cache, http compression, gzip, deflate, minify, CDN, content delivery network, media library, wp cache, wp super cache, w3 total cache, performance, speed
4
  Requires at least: 2.5
5
  Tested up to: 2.8.4
6
- Stable tag: 0.7.5.1
7
 
8
  Dramatically improve the user experience of your blog. Add page caching, database caching, minify and content delivery network functionality and more to WordPress.
9
 
10
  == Description ==
11
 
12
- W3 Total Cache improves the user experience of your blog by caching frequent operations, reducing the weight of various theme files and providing transparent content delivery network integration. The goal is to improve the user experience for the readers of your blog without having to change WordPress, your theme, your plugins or how you produce your content. When fully utilized, your blog will be able to sustain extremely high traffic spikes without requiring hardware upgrades or removing features or functionality from your theme.
 
 
13
 
14
  Features and benefits include:
15
 
@@ -27,13 +29,13 @@ In essence, anything that can be automated to squeeze out every bit of server pe
27
 
28
  == Installation ==
29
 
30
- 1. Disable and remove any other caching plugin you may be using &mdash; most plugins have uninstall procedures you can follow. Make sure wp-content/ has 777 permissions (e.g.: # chmod 777 /var/www/vhosts/domain.com/httpdocs/wp-content/) before proceeding.
31
- 1. Unzip and upload the plugin to your plugins directory (wp-content/plugins/) when done wp-content/plugins/w3-total-cache/ should exist. If you have WordPress MU you will need to install this in wp-content/mu-plugins/w3-total-cache/.
32
- 1. Locate and activate the plugin on the plugins page. Set the permisions of wp-content back to 755 (e.g.: # chmod 755 /var/www/vhosts/domain.com/httpdocs/wp-content/) and click through to the General Settings tab.
33
- 1. Select your caching preferences for page, database and minify. If memcached is used this will require you to confirm or modify the default settings and add any additional memcached servers you wish to use. To utilize APC and memcached + memcache installation guides have been provided for those with virtual dedicated or dedicated servers. For those in shared hosting environments, contact your provider to see if either of these are supported.
34
- 1. If you already have a content delivery network provider, proceed to the CDN Settings tab and populate the fields and set your preferences. If you're not running a version of WordPress with the Media Library feature, use the Media Library Import Tool to migrate your post images etc to appropriate locations. If you do not have a CDN provider, you can create and use a subdomain instead, e.g. subdomain.domain.com to improve server response, pipelining performance and progressive render.
35
- 1. On the Minify Settings tab all of the recommended settings are preset. Specify any CSS and JS files in the respective sections, view your site's HTML source and search for .css and .js files. In the case of JS files you can determine the type and location of the embedding using the drop down menu. Avoid the inclusion of packed or obfuscated JS files in this step.
36
- 1. Enable the plugin on the General Settings tab.
37
  1. You're done! Get back to blogging!
38
 
39
  == Frequently Asked Questions ==
@@ -78,6 +80,19 @@ Not sure, we'll get to that soon.
78
 
79
  On the contrary, as with any other action a user can perform on a site, faster performance will encourage more of it. The cache is so quickly rebuilt in memory that it's no trouble to show visitors the most current version of a post that's experiencing Digg, Slashdot, Drudge Report, Yahoo Buzz or Twitter effect.
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  = Why would I want to cache my feeds? =
82
 
83
  We feel that caching objects after the first request and checking for updates before responding subsequent requests (which is kind of how web browsers work too) creates more opportunities for interesting applications and mashups where the blogosphere doesn't require institutional investment to be able to handle developers making hundreds of requests every day the same way we use Google, Twitter and Facebook (for example) APIs today. Think about it, even when major search engines crawl your site, they have to be "gentle" so they don't bring it down, let's turn the paradigm around so that every blog can deliver content in real-time in various ways.
@@ -92,11 +107,7 @@ Yes, indirectly - if you have a lot of bloggers working with you, you will find
92
 
93
  = Which web servers do you support? =
94
 
95
- We are aware of no incompatibilities with [apache](http://httpd.apache.org/) 1.3+ or [IIS](http://www.iis.net/) 5+. We are still testing [nginx](http://nginx.net/), [litespeed](http://litespeedtech.com/products/webserver/overview/) and [lighttpd](http://www.lighttpd.net/). If you have thoughts or an opinion, we're [interested in hearing](mailto:wordpressexperts@w3-edge.com).
96
-
97
- = Is this plugin compatible with varnish or squid? =
98
-
99
- We are still testing the performance of this plugin with [varnish](http://varnish.projects.linpro.no/). It currently appears that varnish is not necessary when this plugin fully utilized, even when using apache versus litespeed or lighttpd due to the concurrency achieved by memory access for all objects required to handle requests. We have not tested [squid](http://www.squid-cache.org/) with our plugin.
100
 
101
  = Is this plugin server cluster and load balancer friendly? =
102
 
@@ -112,6 +123,17 @@ Install the plugin to read the full FAQ.
112
 
113
  == Changelog ==
114
 
 
 
 
 
 
 
 
 
 
 
 
115
  = 0.7.5.1 =
116
  * Resolved a bug in the minify library preventing proper permission notification messages
117
  * Improved notification handling
@@ -120,7 +142,7 @@ Install the plugin to read the full FAQ.
120
  * Fixed minor issue with URI with CDN functionality enabled
121
  * Removed unnecessary minify options
122
  * Improved reliability of Media Library Export
123
- * Minification error now dialogs disabled when JS or CSS minify settings disabled
124
  * Normalized line endings with /n as per minify author's direction
125
  * Added option to concatenate any script to header or footer with non-blocking options for scripts that cannot be minified (e.g. obfuscated scripts)
126
  * Improved compatibility with suPHP
3
  Tags: user experience, cache, caching, page cache, css cache, js cache, db cache, database cache, http compression, gzip, deflate, minify, CDN, content delivery network, media library, wp cache, wp super cache, w3 total cache, performance, speed
4
  Requires at least: 2.5
5
  Tested up to: 2.8.4
6
+ Stable tag: 0.7.5.2
7
 
8
  Dramatically improve the user experience of your blog. Add page caching, database caching, minify and content delivery network functionality and more to WordPress.
9
 
10
  == Description ==
11
 
12
+ W3 Total Cache improves the user experience of your blog by caching frequent operations, reducing the weight of various theme files and providing transparent content delivery network integration.
13
+
14
+ The goal is to improve the user experience for the readers of your blog without having to change WordPress, your theme, your plugins or how you produce your content. When fully utilized, your blog will be able to sustain extremely high traffic spikes without requiring hardware upgrades or removing features or functionality from your theme.
15
 
16
  Features and benefits include:
17
 
29
 
30
  == Installation ==
31
 
32
+ 1. Disable and remove any other caching plugin you may be using &mdash; most plugins have uninstall procedures you can follow. Make sure wp-content/ has 777 permissions before proceeding, e.g.: `# chmod 777 /var/www/vhosts/domain.com/httpdocs/wp-content/`
33
+ 1. Unzip and upload the plugin to your plugins directory (wp-content/plugins/), when done wp-content/plugins/w3-total-cache/ should exist.
34
+ 1. Ensure that wp-config.php contains the statement below; if you previously used a caching plugin, this statement is likely to exist already: `define('WP_CACHE', true);`
35
+ 1. Locate and activate the plugin on the plugins page, then click the Settings link to proceed to the General Settings tab. Set the permisions of wp-content back to 755, e.g.: `# chmod 755 /var/www/vhosts/domain.com/httpdocs/wp-content/`
36
+ 1. Select your caching preferences for page, database and minify. If memcached is used this will require you to confirm or modify the default settings and add any additional memcached servers you wish to use. To utilize APC and memcached + memcache installation guides have been provided under the Installation tab. For those in shared hosting environments, contact your provider to see if either of these are supported.
37
+ 1. If you already have a content delivery network provider, proceed to the CDN Settings tab and populate the fields and set your preferences. If you're not running a version of WordPress with the Media Library feature, use the Media Library Import Tool to migrate your post images etc to appropriate locations. If you do not have a CDN provider, you can still improve your site's performance using this feature. Create and use a subdomain on your own server; e.g. static.domain.com and configure options on the CDN tab accordingly.
38
+ 1. On the Minify Settings tab all of the recommended settings are preset. Specify any CSS and JS files in the respective sections, view your site's HTML source and search for .css and .js files. In the case of JS files you can specify the type and location of the embedding using the drop down menu.
39
  1. You're done! Get back to blogging!
40
 
41
  == Frequently Asked Questions ==
80
 
81
  On the contrary, as with any other action a user can perform on a site, faster performance will encourage more of it. The cache is so quickly rebuilt in memory that it's no trouble to show visitors the most current version of a post that's experiencing Digg, Slashdot, Drudge Report, Yahoo Buzz or Twitter effect.
82
 
83
+ = Who do you recommend as a CDN (Content Delivery Network) provider? =
84
+
85
+ That depends on how you use your blog and where most of your readers read your blog (regionally). Here's a short list:</p>
86
+
87
+ * [NetDNA](http://www.netdna.com/)
88
+ * [SimpleCDN](http://www.simplecdn.com/)
89
+ * [Amazon S3](http://aws.amazon.com/s3/)
90
+ * [Amazon Cloudfront](http://aws.amazon.com/cloudfront/)
91
+ * [EdgeCast](http://www.edgecast.com/)
92
+ * [Voxel](http://www.voxel.net/products-services/voxcast-cdn)
93
+ * [Limelight Networks](http://www.limelightnetworks.com/)
94
+ * [Akamai](http://www.akamai.com/)
95
+
96
  = Why would I want to cache my feeds? =
97
 
98
  We feel that caching objects after the first request and checking for updates before responding subsequent requests (which is kind of how web browsers work too) creates more opportunities for interesting applications and mashups where the blogosphere doesn't require institutional investment to be able to handle developers making hundreds of requests every day the same way we use Google, Twitter and Facebook (for example) APIs today. Think about it, even when major search engines crawl your site, they have to be "gentle" so they don't bring it down, let's turn the paradigm around so that every blog can deliver content in real-time in various ways.
107
 
108
  = Which web servers do you support? =
109
 
110
+ We are aware of no incompatibilities with [apache](http://httpd.apache.org/) 1.3+, [IIS](http://www.iis.net/) 5+ or [litespeed](http://litespeedtech.com/products/webserver/overview/) 4.0.2+. If there's a web server you feel we should be actively testing (e.g. [lighttpd](http://www.lighttpd.net/)), we're [interested in hearing](mailto:wordpressexperts@w3-edge.com).
 
 
 
 
111
 
112
  = Is this plugin server cluster and load balancer friendly? =
113
 
123
 
124
  == Changelog ==
125
 
126
+ = 0.7.5.2 =
127
+ * Minified files now (optionally) upload automatically according to update interval (expiry time)
128
+ * Provided memcache.ini directives updated to improve network throughput
129
+ * Addressed WordPress MU site-wide activation/deactivation issues
130
+ * Added empty (memcached) cache button to each tab
131
+ * Fixed bug with parsing memcached server strings
132
+ * Added warning dialog to minify tab about removal of query strings locally hosted object URIs
133
+ * Fixed bug with minify sometimes not creating files as it should
134
+ * Changed directory of minify working files to wp-content/w3tc-cache/
135
+ * Improved reliability of memcache flush
136
+
137
  = 0.7.5.1 =
138
  * Resolved a bug in the minify library preventing proper permission notification messages
139
  * Improved notification handling
142
  * Fixed minor issue with URI with CDN functionality enabled
143
  * Removed unnecessary minify options
144
  * Improved reliability of Media Library Export
145
+ * Minification error dialogs now disabled when JS or CSS minify settings disabled
146
  * Normalized line endings with /n as per minify author's direction
147
  * Added option to concatenate any script to header or footer with non-blocking options for scripts that cannot be minified (e.g. obfuscated scripts)
148
  * Improved compatibility with suPHP
tools/apc.php ADDED
@@ -0,0 +1,1362 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ +----------------------------------------------------------------------+
4
+ | APC |
5
+ +----------------------------------------------------------------------+
6
+ | Copyright (c) 2006-2008 The PHP Group |
7
+ +----------------------------------------------------------------------+
8
+ | This source file is subject to version 3.01 of the PHP license, |
9
+ | that is bundled with this package in the file LICENSE, and is |
10
+ | available through the world-wide-web at the following url: |
11
+ | http://www.php.net/license/3_01.txt |
12
+ | If you did not receive a copy of the PHP license and are unable to |
13
+ | obtain it through the world-wide-web, please send a note to |
14
+ | license@php.net so we can mail you a copy immediately. |
15
+ +----------------------------------------------------------------------+
16
+ | Authors: Ralf Becker <beckerr@php.net> |
17
+ | Rasmus Lerdorf <rasmus@php.net> |
18
+ | Ilia Alshanetsky <ilia@prohost.org> |
19
+ +----------------------------------------------------------------------+
20
+
21
+ All other licensing and usage conditions are those of the PHP Group.
22
+
23
+ */
24
+
25
+ $VERSION='$Id: apc.php 271315 2008-12-16 07:15:07Z shire $';
26
+
27
+ ////////// READ OPTIONAL CONFIGURATION FILE ////////////
28
+ if (file_exists("apc.conf.php")) include("apc.conf.php");
29
+ ////////////////////////////////////////////////////////
30
+
31
+ ////////// BEGIN OF DEFAULT CONFIG AREA ///////////////////////////////////////////////////////////
32
+
33
+ defaults('USE_AUTHENTICATION',1); // Use (internal) authentication - best choice if
34
+ // no other authentication is available
35
+ // If set to 0:
36
+ // There will be no further authentication. You
37
+ // will have to handle this by yourself!
38
+ // If set to 1:
39
+ // You need to change ADMIN_PASSWORD to make
40
+ // this work!
41
+ defaults('ADMIN_USERNAME','admin'); // Admin Username
42
+ defaults('ADMIN_PASSWORD','totalcache'); // Admin Password - CHANGE THIS TO ENABLE!!!
43
+
44
+ // (beckerr) I'm using a clear text password here, because I've no good idea how to let
45
+ // users generate a md5 or crypt password in a easy way to fill it in above
46
+
47
+ //defaults('DATE_FORMAT', "d.m.Y H:i:s"); // German
48
+ defaults('DATE_FORMAT', 'Y/m/d H:i:s'); // US
49
+
50
+ defaults('GRAPH_SIZE',200); // Image size
51
+
52
+ //defaults('PROXY', 'tcp://127.0.0.1:8080');
53
+
54
+ ////////// END OF DEFAULT CONFIG AREA /////////////////////////////////////////////////////////////
55
+
56
+
57
+ // "define if not defined"
58
+ function defaults($d,$v) {
59
+ if (!defined($d)) define($d,$v); // or just @define(...)
60
+ }
61
+
62
+ // rewrite $PHP_SELF to block XSS attacks
63
+ //
64
+ $PHP_SELF= isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'],''), ENT_QUOTES, 'UTF-8') : '';
65
+ $time = time();
66
+ $host = php_uname('n');
67
+ if($host) { $host = '('.$host.')'; }
68
+ if ($_SERVER['SERVER_ADDR']) {
69
+ $host .= ' ('.$_SERVER['SERVER_ADDR'].')';
70
+ }
71
+
72
+ // operation constants
73
+ define('OB_HOST_STATS',1);
74
+ define('OB_SYS_CACHE',2);
75
+ define('OB_USER_CACHE',3);
76
+ define('OB_SYS_CACHE_DIR',4);
77
+ define('OB_VERSION_CHECK',9);
78
+
79
+ // check validity of input variables
80
+ $vardom=array(
81
+ 'OB' => '/^\d+$/', // operational mode switch
82
+ 'CC' => '/^[01]$/', // clear cache requested
83
+ 'DU' => '/^.*$/', // Delete User Key
84
+ 'SH' => '/^[a-z0-9]+$/', // shared object description
85
+
86
+ 'IMG' => '/^[123]$/', // image to generate
87
+ 'LO' => '/^1$/', // login requested
88
+
89
+ 'COUNT' => '/^\d+$/', // number of line displayed in list
90
+ 'SCOPE' => '/^[AD]$/', // list view scope
91
+ 'SORT1' => '/^[AHSMCDTZ]$/', // first sort key
92
+ 'SORT2' => '/^[DA]$/', // second sort key
93
+ 'AGGR' => '/^\d+$/', // aggregation by dir level
94
+ 'SEARCH' => '~^[a-zA-Z0-1/_.-]*$~' // aggregation by dir level
95
+ );
96
+
97
+ // default cache mode
98
+ $cache_mode='opcode';
99
+
100
+ // cache scope
101
+ $scope_list=array(
102
+ 'A' => 'cache_list',
103
+ 'D' => 'deleted_list'
104
+ );
105
+
106
+ // handle POST and GET requests
107
+ if (empty($_REQUEST)) {
108
+ if (!empty($_GET) && !empty($_POST)) {
109
+ $_REQUEST = array_merge($_GET, $_POST);
110
+ } else if (!empty($_GET)) {
111
+ $_REQUEST = $_GET;
112
+ } else if (!empty($_POST)) {
113
+ $_REQUEST = $_POST;
114
+ } else {
115
+ $_REQUEST = array();
116
+ }
117
+ }
118
+
119
+ // check parameter syntax
120
+ foreach($vardom as $var => $dom) {
121
+ if (!isset($_REQUEST[$var])) {
122
+ $MYREQUEST[$var]=NULL;
123
+ } else if (!is_array($_REQUEST[$var]) && preg_match($dom.'D',$_REQUEST[$var])) {
124
+ $MYREQUEST[$var]=$_REQUEST[$var];
125
+ } else {
126
+ $MYREQUEST[$var]=$_REQUEST[$var]=NULL;
127
+ }
128
+ }
129
+
130
+ // check parameter sematics
131
+ if (empty($MYREQUEST['SCOPE'])) $MYREQUEST['SCOPE']="A";
132
+ if (empty($MYREQUEST['SORT1'])) $MYREQUEST['SORT1']="H";
133
+ if (empty($MYREQUEST['SORT2'])) $MYREQUEST['SORT2']="D";
134
+ if (empty($MYREQUEST['OB'])) $MYREQUEST['OB']=OB_HOST_STATS;
135
+ if (!isset($MYREQUEST['COUNT'])) $MYREQUEST['COUNT']=20;
136
+ if (!isset($scope_list[$MYREQUEST['SCOPE']])) $MYREQUEST['SCOPE']='A';
137
+
138
+ $MY_SELF=
139
+ "$PHP_SELF".
140
+ "?SCOPE=".$MYREQUEST['SCOPE'].
141
+ "&SORT1=".$MYREQUEST['SORT1'].
142
+ "&SORT2=".$MYREQUEST['SORT2'].
143
+ "&COUNT=".$MYREQUEST['COUNT'];
144
+ $MY_SELF_WO_SORT=
145
+ "$PHP_SELF".
146
+ "?SCOPE=".$MYREQUEST['SCOPE'].
147
+ "&COUNT=".$MYREQUEST['COUNT'];
148
+
149
+ // authentication needed?
150
+ //
151
+ if (!USE_AUTHENTICATION) {
152
+ $AUTHENTICATED=1;
153
+ } else {
154
+ $AUTHENTICATED=0;
155
+ if (ADMIN_PASSWORD!='password' && ($MYREQUEST['LO'] == 1 || isset($_SERVER['PHP_AUTH_USER']))) {
156
+
157
+ if (!isset($_SERVER['PHP_AUTH_USER']) ||
158
+ !isset($_SERVER['PHP_AUTH_PW']) ||
159
+ $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||
160
+ $_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) {
161
+ Header("WWW-Authenticate: Basic realm=\"APC Login\"");
162
+ Header("HTTP/1.0 401 Unauthorized");
163
+
164
+ echo <<<EOB
165
+ <html><body>
166
+ <h1>Rejected!</h1>
167
+ <big>Wrong Username or Password!</big><br/>&nbsp;<br/>&nbsp;
168
+ <big><a href='$PHP_SELF?OB={$MYREQUEST['OB']}'>Continue...</a></big>
169
+ </body></html>
170
+ EOB;
171
+ exit;
172
+
173
+ } else {
174
+ $AUTHENTICATED=1;
175
+ }
176
+ }
177
+ }
178
+
179
+ // select cache mode
180
+ if ($AUTHENTICATED && $MYREQUEST['OB'] == OB_USER_CACHE) {
181
+ $cache_mode='user';
182
+ }
183
+ // clear cache
184
+ if ($AUTHENTICATED && isset($MYREQUEST['CC']) && $MYREQUEST['CC']) {
185
+ apc_clear_cache($cache_mode);
186
+ }
187
+
188
+ if ($AUTHENTICATED && !empty($MYREQUEST['DU'])) {
189
+ apc_delete($MYREQUEST['DU']);
190
+ }
191
+
192
+ if(!function_exists('apc_cache_info') || !($cache=@apc_cache_info($cache_mode))) {
193
+ echo "No cache info available. APC does not appear to be running.";
194
+ exit;
195
+ }
196
+
197
+ $cache_user = apc_cache_info('user', 1);
198
+ $mem=apc_sma_info();
199
+ if(!$cache['num_hits']) { $cache['num_hits']=1; $time++; } // Avoid division by 0 errors on a cache clear
200
+
201
+ // don't cache this page
202
+ //
203
+ header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
204
+ header("Cache-Control: post-check=0, pre-check=0", false);
205
+ header("Pragma: no-cache"); // HTTP/1.0
206
+
207
+ function duration($ts) {
208
+ global $time;
209
+ $years = (int)((($time - $ts)/(7*86400))/52.177457);
210
+ $rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400));
211
+ $weeks = (int)(($rem)/(7*86400));
212
+ $days = (int)(($rem)/86400) - $weeks*7;
213
+ $hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24;
214
+ $mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60;
215
+ $str = '';
216
+ if($years==1) $str .= "$years year, ";
217
+ if($years>1) $str .= "$years years, ";
218
+ if($weeks==1) $str .= "$weeks week, ";
219
+ if($weeks>1) $str .= "$weeks weeks, ";
220
+ if($days==1) $str .= "$days day,";
221
+ if($days>1) $str .= "$days days,";
222
+ if($hours == 1) $str .= " $hours hour and";
223
+ if($hours>1) $str .= " $hours hours and";
224
+ if($mins == 1) $str .= " 1 minute";
225
+ else $str .= " $mins minutes";
226
+ return $str;
227
+ }
228
+
229
+ // create graphics
230
+ //
231
+ function graphics_avail() {
232
+ return extension_loaded('gd');
233
+ }
234
+ if (isset($MYREQUEST['IMG']))
235
+ {
236
+ if (!graphics_avail()) {
237
+ exit(0);
238
+ }
239
+
240
+ function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$color2,$text='',$placeindex=0) {
241
+ $r=$diameter/2;
242
+ $w=deg2rad((360+$start+($end-$start)/2)%360);
243
+
244
+
245
+ if (function_exists("imagefilledarc")) {
246
+ // exists only if GD 2.0.1 is avaliable
247
+ imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE);
248
+ imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE);
249
+ imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED);
250
+ } else {
251
+ imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2);
252
+ imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
253
+ imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start+1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
254
+ imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end-1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
255
+ imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
256
+ imagefill($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $color2);
257
+ }
258
+ if ($text) {
259
+ if ($placeindex>0) {
260
+ imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
261
+ imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
262
+
263
+ } else {
264
+ imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
265
+ }
266
+ }
267
+ }
268
+
269
+ function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$text,$placeindex=0) {
270
+ $r=$diameter/2;
271
+ $w=deg2rad((360+$start+($end-$start)/2)%360);
272
+
273
+ if ($placeindex>0) {
274
+ imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
275
+ imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
276
+
277
+ } else {
278
+ imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
279
+ }
280
+ }
281
+
282
+ function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placeindex='') {
283
+ global $col_black;
284
+ $x1=$x+$w-1;
285
+ $y1=$y+$h-1;
286
+
287
+ imagerectangle($im, $x, $y1, $x1+1, $y+1, $col_black);
288
+ if($y1>$y) imagefilledrectangle($im, $x, $y, $x1, $y1, $color2);
289
+ else imagefilledrectangle($im, $x, $y1, $x1, $y, $color2);
290
+ imagerectangle($im, $x, $y1, $x1, $y, $color1);
291
+ if ($text) {
292
+ if ($placeindex>0) {
293
+
294
+ if ($placeindex<16)
295
+ {
296
+ $px=5;
297
+ $py=$placeindex*12+6;
298
+ imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2);
299
+ imageline($im,$x,$y+$h/2,$px+90,$py,$color2);
300
+ imagestring($im,2,$px,$py-6,$text,$color1);
301
+
302
+ } else {
303
+ if ($placeindex<31) {
304
+ $px=$x+40*2;
305
+ $py=($placeindex-15)*12+6;
306
+ } else {
307
+ $px=$x+40*2+100*intval(($placeindex-15)/15);
308
+ $py=($placeindex%15)*12+6;
309
+ }
310
+ imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2);
311
+ imageline($im,$x+$w,$y+$h/2,$px,$py,$color2);
312
+ imagestring($im,2,$px+2,$py-6,$text,$color1);
313
+ }
314
+ } else {
315
+ imagestring($im,4,$x+5,$y1-16,$text,$color1);
316
+ }
317
+ }
318
+ }
319
+
320
+
321
+ $size = GRAPH_SIZE; // image size
322
+ if ($MYREQUEST['IMG']==3)
323
+ $image = imagecreate(2*$size+150, $size+10);
324
+ else
325
+ $image = imagecreate($size+50, $size+10);
326
+
327
+ $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
328
+ $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30);
329
+ $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60);
330
+ $col_black = imagecolorallocate($image, 0, 0, 0);
331
+ imagecolortransparent($image,$col_white);
332
+
333
+ switch ($MYREQUEST['IMG']) {
334
+
335
+ case 1:
336
+ $s=$mem['num_seg']*$mem['seg_size'];
337
+ $a=$mem['avail_mem'];
338
+ $x=$y=$size/2;
339
+ $fuzz = 0.000001;
340
+
341
+ // This block of code creates the pie chart. It is a lot more complex than you
342
+ // would expect because we try to visualize any memory fragmentation as well.
343
+ $angle_from = 0;
344
+ $string_placement=array();
345
+ for($i=0; $i<$mem['num_seg']; $i++) {
346
+ $ptr = 0;
347
+ $free = $mem['block_lists'][$i];
348
+ uasort($free, 'block_sort');
349
+ foreach($free as $block) {
350
+ if($block['offset']!=$ptr) { // Used block
351
+ $angle_to = $angle_from+($block['offset']-$ptr)/$s;
352
+ if(($angle_to+$fuzz)>1) $angle_to = 1;
353
+ if( ($angle_to*360) - ($angle_from*360) >= 1) {
354
+ fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red);
355
+ if (($angle_to-$angle_from)>0.05) {
356
+ array_push($string_placement, array($angle_from,$angle_to));
357
+ }
358
+ }
359
+ $angle_from = $angle_to;
360
+ }
361
+ $angle_to = $angle_from+($block['size'])/$s;
362
+ if(($angle_to+$fuzz)>1) $angle_to = 1;
363
+ if( ($angle_to*360) - ($angle_from*360) >= 1) {
364
+ fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_green);
365
+ if (($angle_to-$angle_from)>0.05) {
366
+ array_push($string_placement, array($angle_from,$angle_to));
367
+ }
368
+ }
369
+ $angle_from = $angle_to;
370
+ $ptr = $block['offset']+$block['size'];
371
+ }
372
+ if ($ptr < $mem['seg_size']) { // memory at the end
373
+ $angle_to = $angle_from + ($mem['seg_size'] - $ptr)/$s;
374
+ if(($angle_to+$fuzz)>1) $angle_to = 1;
375
+ fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red);
376
+ if (($angle_to-$angle_from)>0.05) {
377
+ array_push($string_placement, array($angle_from,$angle_to));
378
+ }
379
+ }
380
+ }
381
+ foreach ($string_placement as $angle) {
382
+ text_arc($image,$x,$y,$size,$angle[0]*360,$angle[1]*360,$col_black,bsize($s*($angle[1]-$angle[0])));
383
+ }
384
+ break;
385
+
386
+ case 2:
387
+ $s=$cache['num_hits']+$cache['num_misses'];
388
+ $a=$cache['num_hits'];
389
+
390
+ fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s));
391
+ fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s));
392
+ break;
393
+
394
+ case 3:
395
+ $s=$mem['num_seg']*$mem['seg_size'];
396
+ $a=$mem['avail_mem'];
397
+ $x=130;
398
+ $y=1;
399
+ $j=1;
400
+
401
+ // This block of code creates the bar chart. It is a lot more complex than you
402
+ // would expect because we try to visualize any memory fragmentation as well.
403
+ for($i=0; $i<$mem['num_seg']; $i++) {
404
+ $ptr = 0;
405
+ $free = $mem['block_lists'][$i];
406
+ uasort($free, 'block_sort');
407
+ foreach($free as $block) {
408
+ if($block['offset']!=$ptr) { // Used block
409
+ $h=(GRAPH_SIZE-5)*($block['offset']-$ptr)/$s;
410
+ if ($h>0) {
411
+ $j++;
412
+ if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($block['offset']-$ptr),$j);
413
+ else fill_box($image,$x,$y,50,$h,$col_black,$col_red);
414
+ }
415
+ $y+=$h;
416
+ }
417
+ $h=(GRAPH_SIZE-5)*($block['size'])/$s;
418
+ if ($h>0) {
419
+ $j++;
420
+ if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_green,bsize($block['size']),$j);
421
+ else fill_box($image,$x,$y,50,$h,$col_black,$col_green);
422
+ }
423
+ $y+=$h;
424
+ $ptr = $block['offset']+$block['size'];
425
+ }
426
+ if ($ptr < $mem['seg_size']) { // memory at the end
427
+ $h = (GRAPH_SIZE-5) * ($mem['seg_size'] - $ptr) / $s;
428
+ if ($h > 0) {
429
+ fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($mem['seg_size']-$ptr),$j++);
430
+ }
431
+ }
432
+ }
433
+ break;
434
+ case 4:
435
+ $s=$cache['num_hits']+$cache['num_misses'];
436
+ $a=$cache['num_hits'];
437
+
438
+ fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s));
439
+ fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s));
440
+ break;
441
+
442
+ }
443
+ header("Content-type: image/png");
444
+ imagepng($image);
445
+ exit;
446
+ }
447
+
448
+ // pretty printer for byte values
449
+ //
450
+ function bsize($s) {
451
+ foreach (array('','K','M','G') as $i => $k) {
452
+ if ($s < 1024) break;
453
+ $s/=1024;
454
+ }
455
+ return sprintf("%5.1f %sBytes",$s,$k);
456
+ }
457
+
458
+ // sortable table header in "scripts for this host" view
459
+ function sortheader($key,$name,$extra='') {
460
+ global $MYREQUEST, $MY_SELF_WO_SORT;
461
+
462
+ if ($MYREQUEST['SORT1']==$key) {
463
+ $MYREQUEST['SORT2'] = $MYREQUEST['SORT2']=='A' ? 'D' : 'A';
464
+ }
465
+ return "<a class=sortable href=\"$MY_SELF_WO_SORT$extra&SORT1=$key&SORT2=".$MYREQUEST['SORT2']."\">$name</a>";
466
+
467
+ }
468
+
469
+ // create menu entry
470
+ function menu_entry($ob,$title) {
471
+ global $MYREQUEST,$MY_SELF;
472
+ if ($MYREQUEST['OB']!=$ob) {
473
+ return "<li><a href=\"$MY_SELF&OB=$ob\">$title</a></li>";
474
+ } else if (empty($MYREQUEST['SH'])) {
475
+ return "<li><span class=active>$title</span></li>";
476
+ } else {
477
+ return "<li><a class=\"child_active\" href=\"$MY_SELF&OB=$ob\">$title</a></li>";
478
+ }
479
+ }
480
+
481
+ function put_login_link($s="Login")
482
+ {
483
+ global $MY_SELF,$MYREQUEST,$AUTHENTICATED;
484
+ // needs ADMIN_PASSWORD to be changed!
485
+ //
486
+ if (!USE_AUTHENTICATION) {
487
+ return;
488
+ } else if (ADMIN_PASSWORD=='password')
489
+ {
490
+ print <<<EOB
491
+ <a href="#" onClick="javascript:alert('You need to set a password at the top of apc.php before this will work!');return false";>$s</a>
492
+ EOB;
493
+ } else if ($AUTHENTICATED) {
494
+ print <<<EOB
495
+ '{$_SERVER['PHP_AUTH_USER']}'&nbsp;logged&nbsp;in!
496
+ EOB;
497
+ } else{
498
+ print <<<EOB
499
+ <a href="$MY_SELF&LO=1&OB={$MYREQUEST['OB']}">$s</a>
500
+ EOB;
501
+ }
502
+ }
503
+
504
+ function block_sort($array1, $array2)
505
+ {
506
+ if ($array1['offset'] > $array2['offset']) {
507
+ return 1;
508
+ } else {
509
+ return -1;
510
+ }
511
+ }
512
+
513
+
514
+ ?>
515
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
516
+ <html>
517
+ <head><title>APC INFO <?php echo $host ?></title>
518
+ <style><!--
519
+ body { background:white; font-size:100.01%; margin:0; padding:0; }
520
+ body,p,td,th,input,submit { font-size:0.8em;font-family:arial,helvetica,sans-serif; }
521
+ * html body {font-size:0.8em}
522
+ * html p {font-size:0.8em}
523
+ * html td {font-size:0.8em}
524
+ * html th {font-size:0.8em}
525
+ * html input {font-size:0.8em}
526
+ * html submit {font-size:0.8em}
527
+ td { vertical-align:top }
528
+ a { color:black; font-weight:none; text-decoration:none; }
529
+ a:hover { text-decoration:underline; }
530
+ div.content { padding:1em 1em 1em 1em; position:absolute; width:97%; z-index:100; }
531
+
532
+
533
+ div.head div.login {
534
+ position:absolute;
535
+ right: 1em;
536
+ top: 1.2em;
537
+ color:white;
538
+ width:6em;
539
+ }
540
+ div.head div.login a {
541
+ position:absolute;
542
+ right: 0em;
543
+ background:rgb(119,123,180);
544
+ border:solid rgb(102,102,153) 2px;
545
+ color:white;
546
+ font-weight:bold;
547
+ padding:0.1em 0.5em 0.1em 0.5em;
548
+ text-decoration:none;
549
+ }
550
+ div.head div.login a:hover {
551
+ background:rgb(193,193,244);
552
+ }
553
+
554
+ h1.apc { background:rgb(153,153,204); margin:0; padding:0.5em 1em 0.5em 1em; }
555
+ * html h1.apc { margin-bottom:-7px; }
556
+ h1.apc a:hover { text-decoration:none; color:rgb(90,90,90); }
557
+ h1.apc div.logo span.logo {
558
+ background:rgb(119,123,180);
559
+ color:black;
560
+ border-right: solid black 1px;
561
+ border-bottom: solid black 1px;
562
+ font-style:italic;
563
+ font-size:1em;
564
+ padding-left:1.2em;
565
+ padding-right:1.2em;
566
+ text-align:right;
567
+ }
568
+ h1.apc div.logo span.name { color:white; font-size:0.7em; padding:0 0.8em 0 2em; }
569
+ h1.apc div.nameinfo { color:white; display:inline; font-size:0.4em; margin-left: 3em; }
570
+ h1.apc div.copy { color:black; font-size:0.4em; position:absolute; right:1em; }
571
+ hr.apc {
572
+ background:white;
573
+ border-bottom:solid rgb(102,102,153) 1px;
574
+ border-style:none;
575
+ border-top:solid rgb(102,102,153) 10px;
576
+ height:12px;
577
+ margin:0;
578
+ margin-top:1px;
579
+ padding:0;
580
+ }
581
+
582
+ ol,menu { margin:1em 0 0 0; padding:0.2em; margin-left:1em;}
583
+ ol.menu li { display:inline; margin-right:0.7em; list-style:none; font-size:85%}
584
+ ol.menu a {
585
+ background:rgb(153,153,204);
586
+ border:solid rgb(102,102,153) 2px;
587
+ color:white;
588
+ font-weight:bold;
589
+ margin-right:0em;
590
+ padding:0.1em 0.5em 0.1em 0.5em;
591
+ text-decoration:none;
592
+ margin-left: 5px;
593
+ }
594
+ ol.menu a.child_active {
595
+ background:rgb(153,153,204);
596
+ border:solid rgb(102,102,153) 2px;
597
+ color:white;
598
+ font-weight:bold;
599
+ margin-right:0em;
600
+ padding:0.1em 0.5em 0.1em 0.5em;
601
+ text-decoration:none;
602
+ border-left: solid black 5px;
603
+ margin-left: 0px;
604
+ }
605
+ ol.menu span.active {
606
+ background:rgb(153,153,204);
607
+ border:solid rgb(102,102,153) 2px;
608
+ color:black;
609
+ font-weight:bold;
610
+ margin-right:0em;
611
+ padding:0.1em 0.5em 0.1em 0.5em;
612
+ text-decoration:none;
613
+ border-left: solid black 5px;
614
+ }
615
+ ol.menu span.inactive {
616
+ background:rgb(193,193,244);
617
+ border:solid rgb(182,182,233) 2px;
618
+ color:white;
619
+ font-weight:bold;
620
+ margin-right:0em;
621
+ padding:0.1em 0.5em 0.1em 0.5em;
622
+ text-decoration:none;
623
+ margin-left: 5px;
624
+ }
625
+ ol.menu a:hover {
626
+ background:rgb(193,193,244);
627
+ text-decoration:none;
628
+ }
629
+
630
+
631
+ div.info {
632
+ background:rgb(204,204,204);
633
+ border:solid rgb(204,204,204) 1px;
634
+ margin-bottom:1em;
635
+ }
636
+ div.info h2 {
637
+ background:rgb(204,204,204);
638
+ color:black;
639
+ font-size:1em;
640
+ margin:0;
641
+ padding:0.1em 1em 0.1em 1em;
642
+ }
643
+ div.info table {
644
+ border:solid rgb(204,204,204) 1px;
645
+ border-spacing:0;
646
+ width:100%;
647
+ }
648
+ div.info table th {
649
+ background:rgb(204,204,204);
650
+ color:white;
651
+ margin:0;
652
+ padding:0.1em 1em 0.1em 1em;
653
+ }
654
+ div.info table th a.sortable { color:black; }
655
+ div.info table tr.tr-0 { background:rgb(238,238,238); }
656
+ div.info table tr.tr-1 { background:rgb(221,221,221); }
657
+ div.info table td { padding:0.3em 1em 0.3em 1em; }
658
+ div.info table td.td-0 { border-right:solid rgb(102,102,153) 1px; white-space:nowrap; }
659
+ div.info table td.td-n { border-right:solid rgb(102,102,153) 1px; }
660
+ div.info table td h3 {
661
+ color:black;
662
+ font-size:1.1em;
663
+ margin-left:-0.3em;
664
+ }
665
+
666
+ div.graph { margin-bottom:1em }
667
+ div.graph h2 { background:rgb(204,204,204);; color:black; font-size:1em; margin:0; padding:0.1em 1em 0.1em 1em; }
668
+ div.graph table { border:solid rgb(204,204,204) 1px; color:black; font-weight:normal; width:100%; }
669
+ div.graph table td.td-0 { background:rgb(238,238,238); }
670
+ div.graph table td.td-1 { background:rgb(221,221,221); }
671
+ div.graph table td { padding:0.2em 1em 0.4em 1em; }
672
+
673
+ div.div1,div.div2 { margin-bottom:1em; width:35em; }
674
+ div.div3 { position:absolute; left:40em; top:1em; width:580px; }
675
+ //div.div3 { position:absolute; left:37em; top:1em; right:1em; }
676
+
677
+ div.sorting { margin:1.5em 0em 1.5em 2em }
678
+ .center { text-align:center }
679
+ .aright { position:absolute;right:1em }
680
+ .right { text-align:right }
681
+ .ok { color:rgb(0,200,0); font-weight:bold}
682
+ .failed { color:rgb(200,0,0); font-weight:bold}
683
+
684
+ span.box {
685
+ border: black solid 1px;
686
+ border-right:solid black 2px;
687
+ border-bottom:solid black 2px;
688
+ padding:0 0.5em 0 0.5em;
689
+ margin-right:1em;
690
+ }
691
+ span.green { background:#60F060; padding:0 0.5em 0 0.5em}
692
+ span.red { background:#D06030; padding:0 0.5em 0 0.5em }
693
+
694
+ div.authneeded {
695
+ background:rgb(238,238,238);
696
+ border:solid rgb(204,204,204) 1px;
697
+ color:rgb(200,0,0);
698
+ font-size:1.2em;
699
+ font-weight:bold;
700
+ padding:2em;
701
+ text-align:center;
702
+ }
703
+
704
+ input {
705
+ background:rgb(153,153,204);
706
+ border:solid rgb(102,102,153) 2px;
707
+ color:white;
708
+ font-weight:bold;
709
+ margin-right:1em;
710
+ padding:0.1em 0.5em 0.1em 0.5em;
711
+ }
712
+ //-->
713
+ </style>
714
+ </head>
715
+ <body>
716
+ <div class="head">
717
+ <h1 class="apc">
718
+ <div class="logo"><span class="logo"><a href="http://pecl.php.net/package/APC">APC</a></span></div>
719
+ <div class="nameinfo">Opcode Cache</div>
720
+ </h1>
721
+ <div class="login">
722
+ <?php put_login_link(); ?>
723
+ </div>
724
+ <hr class="apc">
725
+ </div>
726
+ <?php
727
+
728
+
729
+ // Display main Menu
730
+ echo <<<EOB
731
+ <ol class=menu>
732
+ <li><a href="$MY_SELF&OB={$MYREQUEST['OB']}&SH={$MYREQUEST['SH']}">Refresh Data</a></li>
733
+ EOB;
734
+ echo
735
+ menu_entry(1,'View Host Stats'),
736
+ menu_entry(2,'System Cache Entries');
737
+ if ($AUTHENTICATED) {
738
+ echo menu_entry(4,'Per-Directory Entries');
739
+ }
740
+ echo
741
+ menu_entry(3,'User Cache Entries'),
742
+ menu_entry(9,'Version Check');
743
+
744
+ if ($AUTHENTICATED) {
745
+ echo <<<EOB
746
+ <li><a class="aright" href="$MY_SELF&CC=1&OB={$MYREQUEST['OB']}" onClick="javascipt:return confirm('Are you sure?');">Clear $cache_mode Cache</a></li>
747
+ EOB;
748
+ }
749
+ echo <<<EOB
750
+ </ol>
751
+ EOB;
752
+
753
+
754
+ // CONTENT
755
+ echo <<<EOB
756
+ <div class=content>
757
+ EOB;
758
+
759
+ // MAIN SWITCH STATEMENT
760
+
761
+ switch ($MYREQUEST['OB']) {
762
+
763
+
764
+
765
+
766
+
767
+ // -----------------------------------------------
768
+ // Host Stats
769
+ // -----------------------------------------------
770
+ case OB_HOST_STATS:
771
+ $mem_size = $mem['num_seg']*$mem['seg_size'];
772
+ $mem_avail= $mem['avail_mem'];
773
+ $mem_used = $mem_size-$mem_avail;
774
+ $seg_size = bsize($mem['seg_size']);
775
+ $req_rate = sprintf("%.2f",($cache['num_hits']+$cache['num_misses'])/($time-$cache['start_time']));
776
+ $hit_rate = sprintf("%.2f",($cache['num_hits'])/($time-$cache['start_time']));
777
+ $miss_rate = sprintf("%.2f",($cache['num_misses'])/($time-$cache['start_time']));
778
+ $insert_rate = sprintf("%.2f",($cache['num_inserts'])/($time-$cache['start_time']));
779
+ $req_rate_user = sprintf("%.2f",($cache_user['num_hits']+$cache_user['num_misses'])/($time-$cache_user['start_time']));
780
+ $hit_rate_user = sprintf("%.2f",($cache_user['num_hits'])/($time-$cache_user['start_time']));
781
+ $miss_rate_user = sprintf("%.2f",($cache_user['num_misses'])/($time-$cache_user['start_time']));
782
+ $insert_rate_user = sprintf("%.2f",($cache_user['num_inserts'])/($time-$cache_user['start_time']));
783
+ $apcversion = phpversion('apc');
784
+ $phpversion = phpversion();
785
+ $number_files = $cache['num_entries'];
786
+ $size_files = bsize($cache['mem_size']);
787
+ $number_vars = $cache_user['num_entries'];
788
+ $size_vars = bsize($cache_user['mem_size']);
789
+ $i=0;
790
+ echo <<< EOB
791
+ <div class="info div1"><h2>General Cache Information</h2>
792
+ <table cellspacing=0><tbody>
793
+ <tr class=tr-0><td class=td-0>APC Version</td><td>$apcversion</td></tr>
794
+ <tr class=tr-1><td class=td-0>PHP Version</td><td>$phpversion</td></tr>
795
+ EOB;
796
+
797
+ if(!empty($_SERVER['SERVER_NAME']))
798
+ echo "<tr class=tr-0><td class=td-0>APC Host</td><td>{$_SERVER['SERVER_NAME']} $host</td></tr>\n";
799
+ if(!empty($_SERVER['SERVER_SOFTWARE']))
800
+ echo "<tr class=tr-1><td class=td-0>Server Software</td><td>{$_SERVER['SERVER_SOFTWARE']}</td></tr>\n";
801
+
802
+ echo <<<EOB
803
+ <tr class=tr-0><td class=td-0>Shared Memory</td><td>{$mem['num_seg']} Segment(s) with $seg_size
804
+ <br/> ({$cache['memory_type']} memory, {$cache['locking_type']} locking)
805
+ </td></tr>
806
+ EOB;
807
+ echo '<tr class=tr-1><td class=td-0>Start Time</td><td>',date(DATE_FORMAT,$cache['start_time']),'</td></tr>';
808
+ echo '<tr class=tr-0><td class=td-0>Uptime</td><td>',duration($cache['start_time']),'</td></tr>';
809
+ echo '<tr class=tr-1><td class=td-0>File Upload Support</td><td>',$cache['file_upload_progress'],'</td></tr>';
810
+ echo <<<EOB
811
+ </tbody></table>
812
+ </div>
813
+
814
+ <div class="info div1"><h2>File Cache Information</h2>
815
+ <table cellspacing=0><tbody>
816
+ <tr class=tr-0><td class=td-0>Cached Files</td><td>$number_files ($size_files)</td></tr>
817
+ <tr class=tr-1><td class=td-0>Hits</td><td>{$cache['num_hits']}</td></tr>
818
+ <tr class=tr-0><td class=td-0>Misses</td><td>{$cache['num_misses']}</td></tr>
819
+ <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate cache requests/second</td></tr>
820
+ <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate cache requests/second</td></tr>
821
+ <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate cache requests/second</td></tr>
822
+ <tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate cache requests/second</td></tr>
823
+ <tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache['expunges']}</td></tr>
824
+ </tbody></table>
825
+ </div>
826
+
827
+ <div class="info div1"><h2>User Cache Information</h2>
828
+ <table cellspacing=0><tbody>
829
+ <tr class=tr-0><td class=td-0>Cached Variables</td><td>$number_vars ($size_vars)</td></tr>
830
+ <tr class=tr-1><td class=td-0>Hits</td><td>{$cache_user['num_hits']}</td></tr>
831
+ <tr class=tr-0><td class=td-0>Misses</td><td>{$cache_user['num_misses']}</td></tr>
832
+ <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate_user cache requests/second</td></tr>
833
+ <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate_user cache requests/second</td></tr>
834
+ <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate_user cache requests/second</td></tr>
835
+ <tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate_user cache requests/second</td></tr>
836
+ <tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache_user['expunges']}</td></tr>
837
+
838
+ </tbody></table>
839
+ </div>
840
+
841
+ <div class="info div2"><h2>Runtime Settings</h2><table cellspacing=0><tbody>
842
+ EOB;
843
+
844
+ $j = 0;
845
+ foreach (ini_get_all('apc') as $k => $v) {
846
+ echo "<tr class=tr-$j><td class=td-0>",$k,"</td><td>",str_replace(',',',<br />',$v['local_value']),"</td></tr>\n";
847
+ $j = 1 - $j;
848
+ }
849
+
850
+ if($mem['num_seg']>1 || $mem['num_seg']==1 && count($mem['block_lists'][0])>1)
851
+ $mem_note = "Memory Usage<br /><font size=-2>(multiple slices indicate fragments)</font>";
852
+ else
853
+ $mem_note = "Memory Usage";
854
+
855
+ echo <<< EOB
856
+ </tbody></table>
857
+ </div>
858
+
859
+ <div class="graph div3"><h2>Host Status Diagrams</h2>
860
+ <table cellspacing=0><tbody>
861
+ EOB;
862
+ $size='width='.(GRAPH_SIZE+50).' height='.(GRAPH_SIZE+10);
863
+ echo <<<EOB
864
+ <tr>
865
+ <td class=td-0>$mem_note</td>
866
+ <td class=td-1>Hits &amp; Misses</td>
867
+ </tr>
868
+ EOB;
869
+
870
+ echo
871
+ graphics_avail() ?
872
+ '<tr>'.
873
+ "<td class=td-0><img alt=\"\" $size src=\"$PHP_SELF?IMG=1&$time\"></td>".
874
+ "<td class=td-1><img alt=\"\" $size src=\"$PHP_SELF?IMG=2&$time\"></td></tr>\n"
875
+ : "",
876
+ '<tr>',
877
+ '<td class=td-0><span class="green box">&nbsp;</span>Free: ',bsize($mem_avail).sprintf(" (%.1f%%)",$mem_avail*100/$mem_size),"</td>\n",
878
+ '<td class=td-1><span class="green box">&nbsp;</span>Hits: ',$cache['num_hits'].sprintf(" (%.1f%%)",$cache['num_hits']*100/($cache['num_hits']+$cache['num_misses'])),"</td>\n",
879
+ '</tr>',
880
+ '<tr>',
881
+ '<td class=td-0><span class="red box">&nbsp;</span>Used: ',bsize($mem_used ).sprintf(" (%.1f%%)",$mem_used *100/$mem_size),"</td>\n",
882
+ '<td class=td-1><span class="red box">&nbsp;</span>Misses: ',$cache['num_misses'].sprintf(" (%.1f%%)",$cache['num_misses']*100/($cache['num_hits']+$cache['num_misses'])),"</td>\n";
883
+ echo <<< EOB
884
+ </tr>
885
+ </tbody></table>
886
+
887
+ <br/>
888
+ <h2>Detailed Memory Usage and Fragmentation</h2>
889
+ <table cellspacing=0><tbody>
890
+ <tr>
891
+ <td class=td-0 colspan=2><br/>
892
+ EOB;
893
+
894
+ // Fragementation: (freeseg - 1) / total_seg
895
+ $nseg = $freeseg = $fragsize = $freetotal = 0;
896
+ for($i=0; $i<$mem['num_seg']; $i++) {
897
+ $ptr = 0;
898
+ foreach($mem['block_lists'][$i] as $block) {
899
+ if ($block['offset'] != $ptr) {
900
+ ++$nseg;
901
+ }
902
+ $ptr = $block['offset'] + $block['size'];
903
+ /* Only consider blocks <5M for the fragmentation % */
904
+ if($block['size']<(5*1024*1024)) $fragsize+=$block['size'];
905
+ $freetotal+=$block['size'];
906
+ }
907
+ $freeseg += count($mem['block_lists'][$i]);
908
+ }
909
+
910
+ if ($freeseg > 1) {
911
+ $frag = sprintf("%.2f%% (%s out of %s in %d fragments)", ($fragsize/$freetotal)*100,bsize($fragsize),bsize($freetotal),$freeseg);
912
+ } else {
913
+ $frag = "0%";
914
+ }
915
+
916
+ if (graphics_avail()) {
917
+ $size='width='.(2*GRAPH_SIZE+150).' height='.(GRAPH_SIZE+10);
918
+ echo <<<EOB
919
+ <img alt="" $size src="$PHP_SELF?IMG=3&$time">
920
+ EOB;
921
+ }
922
+ echo <<<EOB
923
+ </br>Fragmentation: $frag
924
+ </td>
925
+ </tr>
926
+ EOB;
927
+ if(isset($mem['adist'])) {
928
+ foreach($mem['adist'] as $i=>$v) {
929
+ $cur = pow(2,$i); $nxt = pow(2,$i+1)-1;
930
+ if($i==0) $range = "1";
931
+ else $range = "$cur - $nxt";
932
+ echo "<tr><th align=right>$range</th><td align=right>$v</td></tr>\n";
933
+ }
934
+ }
935
+ echo <<<EOB
936
+ </tbody></table>
937
+ </div>
938
+ EOB;
939
+
940
+ break;
941
+
942
+
943
+ // -----------------------------------------------
944
+ // User Cache Entries
945
+ // -----------------------------------------------
946
+ case OB_USER_CACHE:
947
+ if (!$AUTHENTICATED) {
948
+ echo '<div class="error">You need to login to see the user values here!<br/>&nbsp;<br/>';
949
+ put_login_link("Login now!");
950
+ echo '</div>';
951
+ break;
952
+ }
953
+ $fieldname='info';
954
+ $fieldheading='User Entry Label';
955
+ $fieldkey='info';
956
+
957
+ // -----------------------------------------------
958
+ // System Cache Entries
959
+ // -----------------------------------------------
960
+ case OB_SYS_CACHE:
961
+ if (!isset($fieldname))
962
+ {
963
+ $fieldname='filename';
964
+ $fieldheading='Script Filename';
965
+ if(ini_get("apc.stat")) $fieldkey='inode';
966
+ else $fieldkey='filename';
967
+ }
968
+ if (!empty($MYREQUEST['SH']))
969
+ {
970
+ echo <<< EOB
971
+ <div class="info"><table cellspacing=0><tbody>
972
+ <tr><th>Attribute</th><th>Value</th></tr>
973
+ EOB;
974
+
975
+ $m=0;
976
+ foreach($scope_list as $j => $list) {
977
+ foreach($cache[$list] as $i => $entry) {
978
+ if (md5($entry[$fieldkey])!=$MYREQUEST['SH']) continue;
979
+ foreach($entry as $k => $value) {
980
+ if (!$AUTHENTICATED) {
981
+ // hide all path entries if not logged in
982
+ $value=preg_replace('/^.*(\\/|\\\\)/','<i>&lt;hidden&gt;</i>/',$value);
983
+ }
984
+
985
+ if ($k == "num_hits") {
986
+ $value=sprintf("%s (%.2f%%)",$value,$value*100/$cache['num_hits']);
987
+ }
988
+ if ($k == 'deletion_time') {
989
+ if(!$entry['deletion_time']) $value = "None";
990
+ }
991
+ echo
992
+ "<tr class=tr-$m>",
993
+ "<td class=td-0>",ucwords(preg_replace("/_/"," ",$k)),"</td>",
994
+ "<td class=td-last>",(preg_match("/time/",$k) && $value!='None') ? date(DATE_FORMAT,$value) : $value,"</td>",
995
+ "</tr>";
996
+ $m=1-$m;
997
+ }
998
+ if($fieldkey=='info') {
999
+ echo "<tr class=tr-$m><td class=td-0>Stored Value</td><td class=td-last><pre>";
1000
+ $output = var_export(apc_fetch($entry[$fieldkey]),true);
1001
+ echo htmlspecialchars($output);
1002
+ echo "</pre></td></tr>\n";
1003
+ }
1004
+ break;
1005
+ }
1006
+ }
1007
+
1008
+ echo <<<EOB
1009
+ </tbody></table>
1010
+ </div>
1011
+ EOB;
1012
+ break;
1013
+ }
1014
+
1015
+ $cols=6;
1016
+ echo <<<EOB
1017
+ <div class=sorting><form>Scope:
1018
+ <input type=hidden name=OB value={$MYREQUEST['OB']}>
1019
+ <select name=SCOPE>
1020
+ EOB;
1021
+ echo
1022
+ "<option value=A",$MYREQUEST['SCOPE']=='A' ? " selected":"",">Active</option>",
1023
+ "<option value=D",$MYREQUEST['SCOPE']=='D' ? " selected":"",">Deleted</option>",
1024
+ "</select>",
1025
+ ", Sorting:<select name=SORT1>",
1026
+ "<option value=H",$MYREQUEST['SORT1']=='H' ? " selected":"",">Hits</option>",
1027
+ "<option value=Z",$MYREQUEST['SORT1']=='Z' ? " selected":"",">Size</option>",
1028
+ "<option value=S",$MYREQUEST['SORT1']=='S' ? " selected":"",">$fieldheading</option>",
1029
+ "<option value=A",$MYREQUEST['SORT1']=='A' ? " selected":"",">Last accessed</option>",
1030
+ "<option value=M",$MYREQUEST['SORT1']=='M' ? " selected":"",">Last modified</option>",
1031
+ "<option value=C",$MYREQUEST['SORT1']=='C' ? " selected":"",">Created at</option>",
1032
+ "<option value=D",$MYREQUEST['SORT1']=='D' ? " selected":"",">Deleted at</option>";
1033
+ if($fieldname=='info') echo
1034
+ "<option value=D",$MYREQUEST['SORT1']=='T' ? " selected":"",">Timeout</option>";
1035
+ echo
1036
+ '</select>',
1037
+ '<select name=SORT2>',
1038
+ '<option value=D',$MYREQUEST['SORT2']=='D' ? ' selected':'','>DESC</option>',
1039
+ '<option value=A',$MYREQUEST['SORT2']=='A' ? ' selected':'','>ASC</option>',
1040
+ '</select>',
1041
+ '<select name=COUNT onChange="form.submit()">',
1042
+ '<option value=10 ',$MYREQUEST['COUNT']=='10' ? ' selected':'','>Top 10</option>',
1043
+ '<option value=20 ',$MYREQUEST['COUNT']=='20' ? ' selected':'','>Top 20</option>',
1044
+ '<option value=50 ',$MYREQUEST['COUNT']=='50' ? ' selected':'','>Top 50</option>',
1045
+ '<option value=100',$MYREQUEST['COUNT']=='100'? ' selected':'','>Top 100</option>',
1046
+ '<option value=150',$MYREQUEST['COUNT']=='150'? ' selected':'','>Top 150</option>',
1047
+ '<option value=200',$MYREQUEST['COUNT']=='200'? ' selected':'','>Top 200</option>',
1048
+ '<option value=500',$MYREQUEST['COUNT']=='500'? ' selected':'','>Top 500</option>',
1049
+ '<option value=0 ',$MYREQUEST['COUNT']=='0' ? ' selected':'','>All</option>',
1050
+ '</select>',
1051
+ '&nbsp; Search: <input name=SEARCH value="',$MYREQUEST['SEARCH'],'" type=text size=25/>',
1052
+ '&nbsp;<input type=submit value="GO!">',
1053
+ '</form></div>';
1054
+
1055
+ if (isset($MYREQUEST['SEARCH'])) {
1056
+ // Don't use preg_quote because we want the user to be able to specify a
1057
+ // regular expression subpattern.
1058
+ $MYREQUEST['SEARCH'] = '/'.str_replace('/', '\\/', $MYREQUEST['SEARCH']).'/i';
1059
+ if (preg_match($MYREQUEST['SEARCH'], 'test') === false) {
1060
+ echo '<div class="error">Error: enter a valid regular expression as a search query.</div>';
1061
+ break;
1062
+ }
1063
+ }
1064
+
1065
+ echo
1066
+ '<div class="info"><table cellspacing=0><tbody>',
1067
+ '<tr>',
1068
+ '<th>',sortheader('S',$fieldheading, "&OB=".$MYREQUEST['OB']),'</th>',
1069
+ '<th>',sortheader('H','Hits', "&OB=".$MYREQUEST['OB']),'</th>',
1070
+ '<th>',sortheader('Z','Size', "&OB=".$MYREQUEST['OB']),'</th>',
1071
+ '<th>',sortheader('A','Last accessed',"&OB=".$MYREQUEST['OB']),'</th>',
1072
+ '<th>',sortheader('M','Last modified',"&OB=".$MYREQUEST['OB']),'</th>',
1073
+ '<th>',sortheader('C','Created at', "&OB=".$MYREQUEST['OB']),'</th>';
1074
+
1075
+ if($fieldname=='info') {
1076
+ $cols+=2;
1077
+ echo '<th>',sortheader('T','Timeout',"&OB=".$MYREQUEST['OB']),'</th>';
1078
+ }
1079
+ echo '<th>',sortheader('D','Deleted at',"&OB=".$MYREQUEST['OB']),'</th></tr>';
1080
+
1081
+ // builds list with alpha numeric sortable keys
1082
+ //
1083
+ $list = array();
1084
+ foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $i => $entry) {
1085
+ switch($MYREQUEST['SORT1']) {
1086
+ case 'A': $k=sprintf('%015d-',$entry['access_time']); break;
1087
+ case 'H': $k=sprintf('%015d-',$entry['num_hits']); break;
1088
+ case 'Z': $k=sprintf('%015d-',$entry['mem_size']); break;
1089
+ case 'M': $k=sprintf('%015d-',$entry['mtime']); break;
1090
+ case 'C': $k=sprintf('%015d-',$entry['creation_time']); break;
1091
+ case 'T': $k=sprintf('%015d-',$entry['ttl']); break;
1092
+ case 'D': $k=sprintf('%015d-',$entry['deletion_time']); break;
1093
+ case 'S': $k=''; break;
1094
+ }
1095
+ if (!$AUTHENTICATED) {
1096
+ // hide all path entries if not logged in
1097
+ $list[$k.$entry[$fieldname]]=preg_replace('/^.*(\\/|\\\\)/','*hidden*/',$entry);
1098
+ } else {
1099
+ $list[$k.$entry[$fieldname]]=$entry;
1100
+ }
1101
+ }
1102
+
1103
+ if ($list) {
1104
+
1105
+ // sort list
1106
+ //
1107
+ switch ($MYREQUEST['SORT2']) {
1108
+ case "A": krsort($list); break;
1109
+ case "D": ksort($list); break;
1110
+ }
1111
+
1112
+ // output list
1113
+ $i=0;
1114
+ foreach($list as $k => $entry) {
1115
+ if(!$MYREQUEST['SEARCH'] || preg_match($MYREQUEST['SEARCH'], $entry[$fieldname]) != 0) {
1116
+ $field_value = htmlentities(strip_tags($entry[$fieldname],''), ENT_QUOTES, 'UTF-8');
1117
+ echo
1118
+ '<tr class=tr-',$i%2,'>',
1119
+ "<td class=td-0><a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&SH=",md5($entry[$fieldkey]),"\">",$field_value,'</a></td>',
1120
+ '<td class="td-n center">',$entry['num_hits'],'</td>',
1121
+ '<td class="td-n right">',$entry['mem_size'],'</td>',
1122
+ '<td class="td-n center">',date(DATE_FORMAT,$entry['access_time']),'</td>',
1123
+ '<td class="td-n center">',date(DATE_FORMAT,$entry['mtime']),'</td>',
1124
+ '<td class="td-n center">',date(DATE_FORMAT,$entry['creation_time']),'</td>';
1125
+
1126
+ if($fieldname=='info') {
1127
+ if($entry['ttl'])
1128
+ echo '<td class="td-n center">'.$entry['ttl'].' seconds</td>';
1129
+ else
1130
+ echo '<td class="td-n center">None</td>';
1131
+ }
1132
+ if ($entry['deletion_time']) {
1133
+
1134
+ echo '<td class="td-last center">', date(DATE_FORMAT,$entry['deletion_time']), '</td>';
1135
+ } else if ($MYREQUEST['OB'] == OB_USER_CACHE) {
1136
+
1137
+ echo '<td class="td-last center">';
1138
+ echo '[<a href="', $MY_SELF, '&OB=', $MYREQUEST['OB'], '&DU=', urlencode($entry[$fieldkey]), '">Delete Now</a>]';
1139
+ echo '</td>';
1140
+ } else {
1141
+ echo '<td class="td-last center"> &nbsp; </td>';
1142
+ }
1143
+ echo '</tr>';
1144
+ $i++;
1145
+ if ($i == $MYREQUEST['COUNT'])
1146
+ break;
1147
+ }
1148
+ }
1149
+
1150
+ } else {
1151
+ echo '<tr class=tr-0><td class="center" colspan=',$cols,'><i>No data</i></td></tr>';
1152
+ }
1153
+ echo <<< EOB
1154
+ </tbody></table>
1155
+ EOB;
1156
+
1157
+ if ($list && $i < count($list)) {
1158
+ echo "<a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&COUNT=0\"><i>",count($list)-$i,' more available...</i></a>';
1159
+ }
1160
+
1161
+ echo <<< EOB
1162
+ </div>
1163
+ EOB;
1164
+ break;
1165
+
1166
+
1167
+ // -----------------------------------------------
1168
+ // Per-Directory System Cache Entries
1169
+ // -----------------------------------------------
1170
+ case OB_SYS_CACHE_DIR:
1171
+ if (!$AUTHENTICATED) {
1172
+ break;
1173
+ }
1174
+
1175
+ echo <<<EOB
1176
+ <div class=sorting><form>Scope:
1177
+ <input type=hidden name=OB value={$MYREQUEST['OB']}>
1178
+ <select name=SCOPE>
1179
+ EOB;
1180
+ echo
1181
+ "<option value=A",$MYREQUEST['SCOPE']=='A' ? " selected":"",">Active</option>",
1182
+ "<option value=D",$MYREQUEST['SCOPE']=='D' ? " selected":"",">Deleted</option>",
1183
+ "</select>",
1184
+ ", Sorting:<select name=SORT1>",
1185
+ "<option value=H",$MYREQUEST['SORT1']=='H' ? " selected":"",">Total Hits</option>",
1186
+ "<option value=Z",$MYREQUEST['SORT1']=='Z' ? " selected":"",">Total Size</option>",
1187
+ "<option value=T",$MYREQUEST['SORT1']=='T' ? " selected":"",">Number of Files</option>",
1188
+ "<option value=S",$MYREQUEST['SORT1']=='S' ? " selected":"",">Directory Name</option>",
1189
+ "<option value=A",$MYREQUEST['SORT1']=='A' ? " selected":"",">Avg. Size</option>",
1190
+ "<option value=C",$MYREQUEST['SORT1']=='C' ? " selected":"",">Avg. Hits</option>",
1191
+ '</select>',
1192
+ '<select name=SORT2>',
1193
+ '<option value=D',$MYREQUEST['SORT2']=='D' ? ' selected':'','>DESC</option>',
1194
+ '<option value=A',$MYREQUEST['SORT2']=='A' ? ' selected':'','>ASC</option>',
1195
+ '</select>',
1196
+ '<select name=COUNT onChange="form.submit()">',
1197
+ '<option value=10 ',$MYREQUEST['COUNT']=='10' ? ' selected':'','>Top 10</option>',
1198
+ '<option value=20 ',$MYREQUEST['COUNT']=='20' ? ' selected':'','>Top 20</option>',
1199
+ '<option value=50 ',$MYREQUEST['COUNT']=='50' ? ' selected':'','>Top 50</option>',
1200
+ '<option value=100',$MYREQUEST['COUNT']=='100'? ' selected':'','>Top 100</option>',
1201
+ '<option value=150',$MYREQUEST['COUNT']=='150'? ' selected':'','>Top 150</option>',
1202
+ '<option value=200',$MYREQUEST['COUNT']=='200'? ' selected':'','>Top 200</option>',
1203
+ '<option value=500',$MYREQUEST['COUNT']=='500'? ' selected':'','>Top 500</option>',
1204
+ '<option value=0 ',$MYREQUEST['COUNT']=='0' ? ' selected':'','>All</option>',
1205
+ '</select>',
1206
+ ", Group By Dir Level:<select name=AGGR>",
1207
+ "<option value='' selected>None</option>";
1208
+ for ($i = 1; $i < 10; $i++)
1209
+ echo "<option value=$i",$MYREQUEST['AGGR']==$i ? " selected":"",">$i</option>";
1210
+ echo '</select>',
1211
+ '&nbsp;<input type=submit value="GO!">',
1212
+ '</form></div>',
1213
+
1214
+ '<div class="info"><table cellspacing=0><tbody>',
1215
+ '<tr>',
1216
+ '<th>',sortheader('S','Directory Name', "&OB=".$MYREQUEST['OB']),'</th>',
1217
+ '<th>',sortheader('T','Number of Files',"&OB=".$MYREQUEST['OB']),'</th>',
1218
+ '<th>',sortheader('H','Total Hits', "&OB=".$MYREQUEST['OB']),'</th>',
1219
+ '<th>',sortheader('Z','Total Size', "&OB=".$MYREQUEST['OB']),'</th>',
1220
+ '<th>',sortheader('C','Avg. Hits', "&OB=".$MYREQUEST['OB']),'</th>',
1221
+ '<th>',sortheader('A','Avg. Size', "&OB=".$MYREQUEST['OB']),'</th>',
1222
+ '</tr>';
1223
+
1224
+ // builds list with alpha numeric sortable keys
1225
+ //
1226
+ $tmp = $list = array();
1227
+ foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $entry) {
1228
+ $n = dirname($entry['filename']);
1229
+ if ($MYREQUEST['AGGR'] > 0) {
1230
+ $n = preg_replace("!^(/?(?:[^/\\\\]+[/\\\\]){".($MYREQUEST['AGGR']-1)."}[^/\\\\]*).*!", "$1", $n);
1231
+ }
1232
+ if (!isset($tmp[$n])) {
1233
+ $tmp[$n] = array('hits'=>0,'size'=>0,'ents'=>0);
1234
+ }
1235
+ $tmp[$n]['hits'] += $entry['num_hits'];
1236
+ $tmp[$n]['size'] += $entry['mem_size'];
1237
+ ++$tmp[$n]['ents'];
1238
+ }
1239
+
1240
+ foreach ($tmp as $k => $v) {
1241
+ switch($MYREQUEST['SORT1']) {
1242
+ case 'A': $kn=sprintf('%015d-',$v['size'] / $v['ents']);break;
1243
+ case 'T': $kn=sprintf('%015d-',$v['ents']); break;
1244
+ case 'H': $kn=sprintf('%015d-',$v['hits']); break;
1245
+ case 'Z': $kn=sprintf('%015d-',$v['size']); break;
1246
+ case 'C': $kn=sprintf('%015d-',$v['hits'] / $v['ents']);break;
1247
+ case 'S': $kn = $k; break;
1248
+ }
1249
+ $list[$kn.$k] = array($k, $v['ents'], $v['hits'], $v['size']);
1250
+ }
1251
+
1252
+ if ($list) {
1253
+
1254
+ // sort list
1255
+ //
1256
+ switch ($MYREQUEST['SORT2']) {
1257
+ case "A": krsort($list); break;
1258
+ case "D": ksort($list); break;
1259
+ }
1260
+
1261
+ // output list
1262
+ $i = 0;
1263
+ foreach($list as $entry) {
1264
+ echo
1265
+ '<tr class=tr-',$i%2,'>',
1266
+ "<td class=td-0>",$entry[0],'</a></td>',
1267
+ '<td class="td-n center">',$entry[1],'</td>',
1268
+ '<td class="td-n center">',$entry[2],'</td>',
1269
+ '<td class="td-n center">',$entry[3],'</td>',
1270
+ '<td class="td-n center">',round($entry[2] / $entry[1]),'</td>',
1271
+ '<td class="td-n center">',round($entry[3] / $entry[1]),'</td>',
1272
+ '</tr>';
1273
+
1274
+ if (++$i == $MYREQUEST['COUNT']) break;
1275
+ }
1276
+
1277
+ } else {
1278
+ echo '<tr class=tr-0><td class="center" colspan=6><i>No data</i></td></tr>';
1279
+ }
1280
+ echo <<< EOB
1281
+ </tbody></table>
1282
+ EOB;
1283
+
1284
+ if ($list && $i < count($list)) {
1285
+ echo "<a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&COUNT=0\"><i>",count($list)-$i,' more available...</i></a>';
1286
+ }
1287
+
1288
+ echo <<< EOB
1289
+ </div>
1290
+ EOB;
1291
+ break;
1292
+
1293
+ // -----------------------------------------------
1294
+ // Version check
1295
+ // -----------------------------------------------
1296
+ case OB_VERSION_CHECK:
1297
+ echo <<<EOB
1298
+ <div class="info"><h2>APC Version Information</h2>
1299
+ <table cellspacing=0><tbody>
1300
+ <tr>
1301
+ <th></th>
1302
+ </tr>
1303
+ EOB;
1304
+ if (defined('PROXY')) {
1305
+ $ctxt = stream_context_create( array( 'http' => array( 'proxy' => PROXY, 'request_fulluri' => True ) ) );
1306
+ $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss", False, $ctxt);
1307
+ } else {
1308
+ $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss");
1309
+ }
1310
+ if (!$rss) {
1311
+ echo '<tr class="td-last center"><td>Unable to fetch version information.</td></tr>';
1312
+ } else {
1313
+ $apcversion = phpversion('apc');
1314
+
1315
+ preg_match('!<title>APC ([0-9.]+)</title>!', $rss, $match);
1316
+ echo '<tr class="tr-0 center"><td>';
1317
+ if (version_compare($apcversion, $match[1], '>=')) {
1318
+ echo '<div class="ok">You are running the latest version of APC ('.$apcversion.')</div>';
1319
+ $i = 3;
1320
+ } else {
1321
+ echo '<div class="failed">You are running an older version of APC ('.$apcversion.'),
1322
+ newer version '.$match[1].' is available at <a href="http://pecl.php.net/package/APC/'.$match[1].'">
1323
+ http://pecl.php.net/package/APC/'.$match[1].'</a>
1324
+ </div>';
1325
+ $i = -1;
1326
+ }
1327
+ echo '</td></tr>';
1328
+ echo '<tr class="tr-0"><td><h3>Change Log:</h3><br/>';
1329
+
1330
+ preg_match_all('!<(title|description)>([^<]+)</\\1>!', $rss, $match);
1331
+ next($match[2]); next($match[2]);
1332
+
1333
+ while (list(,$v) = each($match[2])) {
1334
+ list(,$ver) = explode(' ', $v, 2);
1335
+ if ($i < 0 && version_compare($apcversion, $ver, '>=')) {
1336
+ break;
1337
+ } else if (!$i--) {
1338
+ break;
1339
+ }
1340
+ echo "<b><a href=\"http://pecl.php.net/package/APC/$ver\">".htmlspecialchars($v)."</a></b><br><blockquote>";
1341
+ echo nl2br(htmlspecialchars(current($match[2])))."</blockquote>";
1342
+ next($match[2]);
1343
+ }
1344
+ echo '</td></tr>';
1345
+ }
1346
+ echo <<< EOB
1347
+ </tbody></table>
1348
+ </div>
1349
+ EOB;
1350
+ break;
1351
+
1352
+ }
1353
+
1354
+ echo <<< EOB
1355
+ </div>
1356
+ EOB;
1357
+
1358
+ ?>
1359
+
1360
+ <!-- <?php echo "\nBased on APCGUI By R.Becker\n$VERSION\n"?> -->
1361
+ </body>
1362
+ </html>
tools/memcache.php ADDED
@@ -0,0 +1,880 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ +----------------------------------------------------------------------+
4
+ | PHP Version 5 |
5
+ +----------------------------------------------------------------------+
6
+ | Copyright (c) 1997-2004 The PHP Group |
7
+ +----------------------------------------------------------------------+
8
+ | This source file is subject to version 3.0 of the PHP license, |
9
+ | that is bundled with this package in the file LICENSE, and is |
10
+ | available through the world-wide-web at the following url: |
11
+ | http://www.php.net/license/3_0.txt. |
12
+ | If you did not receive a copy of the PHP license and are unable to |
13
+ | obtain it through the world-wide-web, please send a note to |
14
+ | license@php.net so we can mail you a copy immediately. |
15
+ +----------------------------------------------------------------------+
16
+ | Author: Harun Yayli <harunyayli at gmail.com> |
17
+ +----------------------------------------------------------------------+
18
+ */
19
+
20
+ $VERSION='$Id: memcache.php,v 1.2 2008/09/11 19:21:06 mikl Exp $';
21
+
22
+ define('ADMIN_USERNAME','admin'); // Admin Username
23
+ define('ADMIN_PASSWORD','totalcache'); // Admin Password
24
+ define('DATE_FORMAT','Y/m/d H:i:s');
25
+ define('GRAPH_SIZE',200);
26
+ define('MAX_ITEM_DUMP',50);
27
+
28
+ $MEMCACHE_SERVERS[] = 'localhost:11211'; // add more as an array
29
+
30
+
31
+ ////////// END OF DEFAULT CONFIG AREA /////////////////////////////////////////////////////////////
32
+
33
+ ///////////////// Password protect ////////////////////////////////////////////////////////////////
34
+ if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) ||
35
+ $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||$_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) {
36
+ Header("WWW-Authenticate: Basic realm=\"Memcache Login\"");
37
+ Header("HTTP/1.0 401 Unauthorized");
38
+
39
+ echo <<<EOB
40
+ <html><body>
41
+ <h1>Rejected!</h1>
42
+ <big>Wrong Username or Password!</big>
43
+ </body></html>
44
+ EOB;
45
+ exit;
46
+ }
47
+
48
+ ///////////MEMCACHE FUNCTIONS /////////////////////////////////////////////////////////////////////
49
+
50
+ function sendMemcacheCommands($command){
51
+ global $MEMCACHE_SERVERS;
52
+ $result = array();
53
+
54
+ foreach($MEMCACHE_SERVERS as $server){
55
+ $strs = explode(':',$server);
56
+ $host = $strs[0];
57
+ $port = $strs[1];
58
+ $result[$server] = sendMemcacheCommand($host,$port,$command);
59
+ }
60
+ return $result;
61
+ }
62
+ function sendMemcacheCommand($server,$port,$command){
63
+
64
+ $s = @fsockopen($server,$port);
65
+ if (!$s){
66
+ die("Cant connect to:".$server.':'.$port);
67
+ }
68
+
69
+ fwrite($s, $command."\r\n");
70
+
71
+ $buf='';
72
+ while ((!feof($s))) {
73
+ $buf .= fgets($s, 256);
74
+ if (strpos($buf,"END\r\n")!==false){ // stat says end
75
+ break;
76
+ }
77
+ if (strpos($buf,"DELETED\r\n")!==false || strpos($buf,"NOT_FOUND\r\n")!==false){ // delete says these
78
+ break;
79
+ }
80
+ if (strpos($buf,"OK\r\n")!==false){ // flush_all says ok
81
+ break;
82
+ }
83
+ }
84
+ fclose($s);
85
+ return parseMemcacheResults($buf);
86
+ }
87
+ function parseMemcacheResults($str){
88
+
89
+ $res = array();
90
+ $lines = explode("\r\n",$str);
91
+ $cnt = count($lines);
92
+ for($i=0; $i< $cnt; $i++){
93
+ $line = $lines[$i];
94
+ $l = explode(' ',$line,3);
95
+ if (count($l)==3){
96
+ $res[$l[0]][$l[1]]=$l[2];
97
+ if ($l[0]=='VALUE'){ // next line is the value
98
+ $res[$l[0]][$l[1]] = array();
99
+ list ($flag,$size)=explode(' ',$l[2]);
100
+ $res[$l[0]][$l[1]]['stat']=array('flag'=>$flag,'size'=>$size);
101
+ $res[$l[0]][$l[1]]['value']=$lines[++$i];
102
+ }
103
+ }elseif($line=='DELETED' || $line=='NOT_FOUND' || $line=='OK'){
104
+ return $line;
105
+ }
106
+ }
107
+ return $res;
108
+
109
+ }
110
+
111
+ function dumpCacheSlab($server,$slabId,$limit){
112
+ list($host,$port) = explode(':',$server);
113
+ $resp = sendMemcacheCommand($host,$port,'stats cachedump '.$slabId.' '.$limit);
114
+
115
+ return $resp;
116
+
117
+ }
118
+
119
+ function flushServer($server){
120
+ list($host,$port) = explode(':',$server);
121
+ $resp = sendMemcacheCommand($host,$port,'flush_all');
122
+ return $resp;
123
+ }
124
+ function getCacheItems(){
125
+ $items = sendMemcacheCommands('stats items');
126
+ $serverItems = array();
127
+ $totalItems = array();
128
+ foreach ($items as $server=>$itemlist){
129
+ $serverItems[$server] = array();
130
+ $totalItems[$server]=0;
131
+ if (!isset($itemlist['STAT'])){
132
+ continue;
133
+ }
134
+
135
+ $iteminfo = $itemlist['STAT'];
136
+
137
+ foreach($iteminfo as $keyinfo=>$value){
138
+ if (preg_match('/items\:(\d+?)\:(.+?)$/',$keyinfo,$matches)){
139
+ $serverItems[$server][$matches[1]][$matches[2]] = $value;
140
+ if ($matches[2]=='number'){
141
+ $totalItems[$server] +=$value;
142
+ }
143
+ }
144
+ }
145
+ }
146
+ return array('items'=>$serverItems,'counts'=>$totalItems);
147
+ }
148
+ function getMemcacheStats($total=true){
149
+ $resp = sendMemcacheCommands('stats');
150
+ if ($total){
151
+ $res = array();
152
+ foreach($resp as $server=>$r){
153
+ foreach($r['STAT'] as $key=>$row){
154
+ if (!isset($res[$key])){
155
+ $res[$key]=null;
156
+ }
157
+ switch ($key){
158
+ case 'pid':
159
+ $res['pid'][$server]=$row;
160
+ break;
161
+ case 'uptime':
162
+ $res['uptime'][$server]=$row;
163
+ break;
164
+ case 'time':
165
+ $res['time'][$server]=$row;
166
+ break;
167
+ case 'version':
168
+ $res['version'][$server]=$row;
169
+ break;
170
+ case 'pointer_size':
171
+ $res['pointer_size'][$server]=$row;
172
+ break;
173
+ case 'rusage_user':
174
+ $res['rusage_user'][$server]=$row;
175
+ break;
176
+ case 'rusage_system':
177
+ $res['rusage_system'][$server]=$row;
178
+ break;
179
+ case 'curr_items':
180
+ $res['curr_items']+=$row;
181
+ break;
182
+ case 'total_items':
183
+ $res['total_items']+=$row;
184
+ break;
185
+ case 'bytes':
186
+ $res['bytes']+=$row;
187
+ break;
188
+ case 'curr_connections':
189
+ $res['curr_connections']+=$row;
190
+ break;
191
+ case 'total_connections':
192
+ $res['total_connections']+=$row;
193
+ break;
194
+ case 'connection_structures':
195
+ $res['connection_structures']+=$row;
196
+ break;
197
+ case 'cmd_get':
198
+ $res['cmd_get']+=$row;
199
+ break;
200
+ case 'cmd_set':
201
+ $res['cmd_set']+=$row;
202
+ break;
203
+ case 'get_hits':
204
+ $res['get_hits']+=$row;
205
+ break;
206
+ case 'get_misses':
207
+ $res['get_misses']+=$row;
208
+ break;
209
+ case 'evictions':
210
+ $res['evictions']+=$row;
211
+ break;
212
+ case 'bytes_read':
213
+ $res['bytes_read']+=$row;
214
+ break;
215
+ case 'bytes_written':
216
+ $res['bytes_written']+=$row;
217
+ break;
218
+ case 'limit_maxbytes':
219
+ $res['limit_maxbytes']+=$row;
220
+ break;
221
+ case 'threads':
222
+ $res['rusage_system'][$server]=$row;
223
+ break;
224
+ }
225
+ }
226
+ }
227
+ return $res;
228
+ }
229
+ return $resp;
230
+ }
231
+
232
+ //////////////////////////////////////////////////////
233
+
234
+ //
235
+ // don't cache this page
236
+ //
237
+ header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
238
+ header("Cache-Control: post-check=0, pre-check=0", false);
239
+ header("Pragma: no-cache"); // HTTP/1.0
240
+
241
+ function duration($ts) {
242
+ global $time;
243
+ $years = (int)((($time - $ts)/(7*86400))/52.177457);
244
+ $rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400));
245
+ $weeks = (int)(($rem)/(7*86400));
246
+ $days = (int)(($rem)/86400) - $weeks*7;
247
+ $hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24;
248
+ $mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60;
249
+ $str = '';
250
+ if($years==1) $str .= "$years year, ";
251
+ if($years>1) $str .= "$years years, ";
252
+ if($weeks==1) $str .= "$weeks week, ";
253
+ if($weeks>1) $str .= "$weeks weeks, ";
254
+ if($days==1) $str .= "$days day,";
255
+ if($days>1) $str .= "$days days,";
256
+ if($hours == 1) $str .= " $hours hour and";
257
+ if($hours>1) $str .= " $hours hours and";
258
+ if($mins == 1) $str .= " 1 minute";
259
+ else $str .= " $mins minutes";
260
+ return $str;
261
+ }
262
+
263
+ // create graphics
264
+ //
265
+ function graphics_avail() {
266
+ return extension_loaded('gd');
267
+ }
268
+
269
+ function bsize($s) {
270
+ foreach (array('','K','M','G') as $i => $k) {
271
+ if ($s < 1024) break;
272
+ $s/=1024;
273
+ }
274
+ return sprintf("%5.1f %sBytes",$s,$k);
275
+ }
276
+
277
+ // create menu entry
278
+ function menu_entry($ob,$title) {
279
+ global $PHP_SELF;
280
+ if ($ob==$_GET['op']){
281
+ return "<li><a class=\"child_active\" href=\"$PHP_SELF&op=$ob\">$title</a></li>";
282
+ }
283
+ return "<li><a class=\"active\" href=\"$PHP_SELF&op=$ob\">$title</a></li>";
284
+ }
285
+
286
+ function getHeader(){
287
+ $header = <<<EOB
288
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
289
+ <html>
290
+ <head><title>MEMCACHE INFO</title>
291
+ <style type="text/css"><!--
292
+ body { background:white; font-size:100.01%; margin:0; padding:0; }
293
+ body,p,td,th,input,submit { font-size:0.8em;font-family:arial,helvetica,sans-serif; }
294
+ * html body {font-size:0.8em}
295
+ * html p {font-size:0.8em}
296
+ * html td {font-size:0.8em}
297
+ * html th {font-size:0.8em}
298
+ * html input {font-size:0.8em}
299
+ * html submit {font-size:0.8em}
300
+ td { vertical-align:top }
301
+ a { color:black; font-weight:none; text-decoration:none; }
302
+ a:hover { text-decoration:underline; }
303
+ div.content { padding:1em 1em 1em 1em; position:absolute; width:97%; z-index:100; }
304
+
305
+ h1.memcache { background:rgb(153,153,204); margin:0; padding:0.5em 1em 0.5em 1em; }
306
+ * html h1.memcache { margin-bottom:-7px; }
307
+ h1.memcache a:hover { text-decoration:none; color:rgb(90,90,90); }
308
+ h1.memcache span.logo {
309
+ background:rgb(119,123,180);
310
+ color:black;
311
+ border-right: solid black 1px;
312
+ border-bottom: solid black 1px;
313
+ font-style:italic;
314
+ font-size:1em;
315
+ padding-left:1.2em;
316
+ padding-right:1.2em;
317
+ text-align:right;
318
+ display:block;
319
+ width:130px;
320
+ }
321
+ h1.memcache span.logo span.name { color:white; font-size:0.7em; padding:0 0.8em 0 2em; }
322
+ h1.memcache span.nameinfo { color:white; display:inline; font-size:0.4em; margin-left: 3em; }
323
+ h1.memcache div.copy { color:black; font-size:0.4em; position:absolute; right:1em; }
324
+ hr.memcache {
325
+ background:white;
326
+ border-bottom:solid rgb(102,102,153) 1px;
327
+ border-style:none;
328
+ border-top:solid rgb(102,102,153) 10px;
329
+ height:12px;
330
+ margin:0;
331
+ margin-top:1px;
332
+ padding:0;
333
+ }
334
+
335
+ ol,menu { margin:1em 0 0 0; padding:0.2em; margin-left:1em;}
336
+ ol.menu li { display:inline; margin-right:0.7em; list-style:none; font-size:85%}
337
+ ol.menu a {
338
+ background:rgb(153,153,204);
339
+ border:solid rgb(102,102,153) 2px;
340
+ color:white;
341
+ font-weight:bold;
342
+ margin-right:0em;
343
+ padding:0.1em 0.5em 0.1em 0.5em;
344
+ text-decoration:none;
345
+ margin-left: 5px;
346
+ }
347
+ ol.menu a.child_active {
348
+ background:rgb(153,153,204);
349
+ border:solid rgb(102,102,153) 2px;
350
+ color:white;
351
+ font-weight:bold;
352
+ margin-right:0em;
353
+ padding:0.1em 0.5em 0.1em 0.5em;
354
+ text-decoration:none;
355
+ border-left: solid black 5px;
356
+ margin-left: 0px;
357
+ }
358
+ ol.menu span.active {
359
+ background:rgb(153,153,204);
360
+ border:solid rgb(102,102,153) 2px;
361
+ color:black;
362
+ font-weight:bold;
363
+ margin-right:0em;
364
+ padding:0.1em 0.5em 0.1em 0.5em;
365
+ text-decoration:none;
366
+ border-left: solid black 5px;
367
+ }
368
+ ol.menu span.inactive {
369
+ background:rgb(193,193,244);
370
+ border:solid rgb(182,182,233) 2px;
371
+ color:white;
372
+ font-weight:bold;
373
+ margin-right:0em;
374
+ padding:0.1em 0.5em 0.1em 0.5em;
375
+ text-decoration:none;
376
+ margin-left: 5px;
377
+ }
378
+ ol.menu a:hover {
379
+ background:rgb(193,193,244);
380
+ text-decoration:none;
381
+ }
382
+
383
+
384
+ div.info {
385
+ background:rgb(204,204,204);
386
+ border:solid rgb(204,204,204) 1px;
387
+ margin-bottom:1em;
388
+ }
389
+ div.info h2 {
390
+ background:rgb(204,204,204);
391
+ color:black;
392
+ font-size:1em;
393
+ margin:0;
394
+ padding:0.1em 1em 0.1em 1em;
395
+ }
396
+ div.info table {
397
+ border:solid rgb(204,204,204) 1px;
398
+ border-spacing:0;
399
+ width:100%;
400
+ }
401
+ div.info table th {
402
+ background:rgb(204,204,204);
403
+ color:white;
404
+ margin:0;
405
+ padding:0.1em 1em 0.1em 1em;
406
+ }
407
+ div.info table th a.sortable { color:black; }
408
+ div.info table tr.tr-0 { background:rgb(238,238,238); }
409
+ div.info table tr.tr-1 { background:rgb(221,221,221); }
410
+ div.info table td { padding:0.3em 1em 0.3em 1em; }
411
+ div.info table td.td-0 { border-right:solid rgb(102,102,153) 1px; white-space:nowrap; }
412
+ div.info table td.td-n { border-right:solid rgb(102,102,153) 1px; }
413
+ div.info table td h3 {
414
+ color:black;
415
+ font-size:1.1em;
416
+ margin-left:-0.3em;
417
+ }
418
+ .td-0 a , .td-n a, .tr-0 a , tr-1 a {
419
+ text-decoration:underline;
420
+ }
421
+ div.graph { margin-bottom:1em }
422
+ div.graph h2 { background:rgb(204,204,204);; color:black; font-size:1em; margin:0; padding:0.1em 1em 0.1em 1em; }
423
+ div.graph table { border:solid rgb(204,204,204) 1px; color:black; font-weight:normal; width:100%; }
424
+ div.graph table td.td-0 { background:rgb(238,238,238); }
425
+ div.graph table td.td-1 { background:rgb(221,221,221); }
426
+ div.graph table td { padding:0.2em 1em 0.4em 1em; }
427
+
428
+ div.div1,div.div2 { margin-bottom:1em; width:35em; }
429
+ div.div3 { position:absolute; left:40em; top:1em; width:580px; }
430
+ //div.div3 { position:absolute; left:37em; top:1em; right:1em; }
431
+
432
+ div.sorting { margin:1.5em 0em 1.5em 2em }
433
+ .center { text-align:center }
434
+ .aright { position:absolute;right:1em }
435
+ .right { text-align:right }
436
+ .ok { color:rgb(0,200,0); font-weight:bold}
437
+ .failed { color:rgb(200,0,0); font-weight:bold}
438
+
439
+ span.box {
440
+ border: black solid 1px;
441
+ border-right:solid black 2px;
442
+ border-bottom:solid black 2px;
443
+ padding:0 0.5em 0 0.5em;
444
+ margin-right:1em;
445
+ }
446
+ span.green { background:#60F060; padding:0 0.5em 0 0.5em}
447
+ span.red { background:#D06030; padding:0 0.5em 0 0.5em }
448
+
449
+ div.authneeded {
450
+ background:rgb(238,238,238);
451
+ border:solid rgb(204,204,204) 1px;
452
+ color:rgb(200,0,0);
453
+ font-size:1.2em;
454
+ font-weight:bold;
455
+ padding:2em;
456
+ text-align:center;
457
+ }
458
+
459
+ input {
460
+ background:rgb(153,153,204);
461
+ border:solid rgb(102,102,153) 2px;
462
+ color:white;
463
+ font-weight:bold;
464
+ margin-right:1em;
465
+ padding:0.1em 0.5em 0.1em 0.5em;
466
+ }
467
+ //-->
468
+ </style>
469
+ </head>
470
+ <body>
471
+ <div class="head">
472
+ <h1 class="memcache">
473
+ <span class="logo"><a href="http://pecl.php.net/package/memcache">memcache</a></span>
474
+ <span class="nameinfo">memcache.php by <a href="http://livebookmark.net">Harun Yayli</a></span>
475
+ </h1>
476
+ <hr class="memcache">
477
+ </div>
478
+ <div class=content>
479
+ EOB;
480
+
481
+ return $header;
482
+ }
483
+ function getFooter(){
484
+ global $VERSION;
485
+ $footer = '</div><!-- Based on apc.php '.$VERSION.'--></body>
486
+ </html>
487
+ ';
488
+
489
+ return $footer;
490
+
491
+ }
492
+ function getMenu(){
493
+ global $PHP_SELF;
494
+ echo "<ol class=menu>";
495
+ if ($_GET['op']!=4){
496
+ echo <<<EOB
497
+ <li><a href="$PHP_SELF&op={$_GET['op']}">Refresh Data</a></li>
498
+ EOB;
499
+ }
500
+ else {
501
+ echo <<<EOB
502
+ <li><a href="$PHP_SELF&op=2}">Back</a></li>
503
+ EOB;
504
+ }
505
+ echo
506
+ menu_entry(1,'View Host Stats'),
507
+ menu_entry(2,'Variables');
508
+
509
+ echo <<<EOB
510
+ </ol>
511
+ <br/>
512
+ EOB;
513
+ }
514
+
515
+ // TODO, AUTH
516
+
517
+ $_GET['op'] = !isset($_GET['op'])? '1':$_GET['op'];
518
+ $PHP_SELF= isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'],'')) : '';
519
+
520
+ $PHP_SELF=$PHP_SELF.'?';
521
+ $time = time();
522
+ // sanitize _GET
523
+
524
+ foreach($_GET as $key=>$g){
525
+ $_GET[$key]=htmlentities($g);
526
+ }
527
+
528
+
529
+ // singleout
530
+ // when singleout is set, it only gives details for that server.
531
+ if (isset($_GET['singleout']) && $_GET['singleout']>=0 && $_GET['singleout'] <count($MEMCACHE_SERVERS)){
532
+ $MEMCACHE_SERVERS = array($MEMCACHE_SERVERS[$_GET['singleout']]);
533
+ }
534
+
535
+ // display images
536
+ if (isset($_GET['IMG'])){
537
+ $memcacheStats = getMemcacheStats();
538
+ $memcacheStatsSingle = getMemcacheStats(false);
539
+
540
+ if (!graphics_avail()) {
541
+ exit(0);
542
+ }
543
+
544
+ function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placeindex='') {
545
+ global $col_black;
546
+ $x1=$x+$w-1;
547
+ $y1=$y+$h-1;
548
+
549
+ imagerectangle($im, $x, $y1, $x1+1, $y+1, $col_black);
550
+ if($y1>$y) imagefilledrectangle($im, $x, $y, $x1, $y1, $color2);
551
+ else imagefilledrectangle($im, $x, $y1, $x1, $y, $color2);
552
+ imagerectangle($im, $x, $y1, $x1, $y, $color1);
553
+ if ($text) {
554
+ if ($placeindex>0) {
555
+
556
+ if ($placeindex<16)
557
+ {
558
+ $px=5;
559
+ $py=$placeindex*12+6;
560
+ imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2);
561
+ imageline($im,$x,$y+$h/2,$px+90,$py,$color2);
562
+ imagestring($im,2,$px,$py-6,$text,$color1);
563
+
564
+ } else {
565
+ if ($placeindex<31) {
566
+ $px=$x+40*2;
567
+ $py=($placeindex-15)*12+6;
568
+ } else {
569
+ $px=$x+40*2+100*intval(($placeindex-15)/15);
570
+ $py=($placeindex%15)*12+6;
571
+ }
572
+ imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2);
573
+ imageline($im,$x+$w,$y+$h/2,$px,$py,$color2);
574
+ imagestring($im,2,$px+2,$py-6,$text,$color1);
575
+ }
576
+ } else {
577
+ imagestring($im,4,$x+5,$y1-16,$text,$color1);
578
+ }
579
+ }
580
+ }
581
+
582
+
583
+ function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$color2,$text='',$placeindex=0) {
584
+ $r=$diameter/2;
585
+ $w=deg2rad((360+$start+($end-$start)/2)%360);
586
+
587
+
588
+ if (function_exists("imagefilledarc")) {
589
+ // exists only if GD 2.0.1 is avaliable
590
+ imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE);
591
+ imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE);
592
+ imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED);
593
+ } else {
594
+ imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2);
595
+ imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
596
+ imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start+1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
597
+ imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end-1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
598
+ imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
599
+ imagefill($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $color2);
600
+ }
601
+ if ($text) {
602
+ if ($placeindex>0) {
603
+ imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
604
+ imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
605
+
606
+ } else {
607
+ imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
608
+ }
609
+ }
610
+ }
611
+ $size = GRAPH_SIZE; // image size
612
+ $image = imagecreate($size+50, $size+10);
613
+
614
+ $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
615
+ $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30);
616
+ $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60);
617
+ $col_black = imagecolorallocate($image, 0, 0, 0);
618
+
619
+ imagecolortransparent($image,$col_white);
620
+
621
+ switch ($_GET['IMG']){
622
+ case 1: // pie chart
623
+ $tsize=$memcacheStats['limit_maxbytes'];
624
+ $avail=$tsize-$memcacheStats['bytes'];
625
+ $x=$y=$size/2;
626
+ $angle_from = 0;
627
+ $fuzz = 0.000001;
628
+
629
+ foreach($memcacheStatsSingle as $serv=>$mcs) {
630
+ $free = $mcs['STAT']['limit_maxbytes']-$mcs['STAT']['bytes'];
631
+ $used = $mcs['STAT']['bytes'];
632
+
633
+
634
+ if ($free>0){
635
+ // draw free
636
+ $angle_to = ($free*360)/$tsize;
637
+ $perc =sprintf("%.2f%%", ($free *100) / $tsize) ;
638
+
639
+ fill_arc($image,$x,$y,$size,$angle_from,$angle_from + $angle_to ,$col_black,$col_green,$perc);
640
+ $angle_from = $angle_from + $angle_to ;
641
+ }
642
+ if ($used>0){
643
+ // draw used
644
+ $angle_to = ($used*360)/$tsize;
645
+ $perc =sprintf("%.2f%%", ($used *100) / $tsize) ;
646
+ fill_arc($image,$x,$y,$size,$angle_from,$angle_from + $angle_to ,$col_black,$col_red, '('.$perc.')' );
647
+ $angle_from = $angle_from+ $angle_to ;
648
+ }
649
+ }
650
+
651
+ break;
652
+
653
+ case 2: // hit miss
654
+
655
+ $hits = ($memcacheStats['get_hits']==0) ? 1:$memcacheStats['get_hits'];
656
+ $misses = ($memcacheStats['get_misses']==0) ? 1:$memcacheStats['get_misses'];
657
+ $total = $hits + $misses ;
658
+
659
+ fill_box($image, 30,$size,50,-$hits*($size-21)/$total,$col_black,$col_green,sprintf("%.1f%%",$hits*100/$total));
660
+ fill_box($image,130,$size,50,-max(4,($total-$hits)*($size-21)/$total),$col_black,$col_red,sprintf("%.1f%%",$misses*100/$total));
661
+ break;
662
+
663
+ }
664
+ header("Content-type: image/png");
665
+ imagepng($image);
666
+ exit;
667
+ }
668
+
669
+ echo getHeader();
670
+ echo getMenu();
671
+
672
+ switch ($_GET['op']) {
673
+
674
+ case 1: // host stats
675
+ $phpversion = phpversion();
676
+ $memcacheStats = getMemcacheStats();
677
+ $memcacheStatsSingle = getMemcacheStats(false);
678
+
679
+ $mem_size = $memcacheStats['limit_maxbytes'];
680
+ $mem_used = $memcacheStats['bytes'];
681
+ $mem_avail= $mem_size-$mem_used;
682
+ $startTime = time()-array_sum($memcacheStats['uptime']);
683
+
684
+ $curr_items = $memcacheStats['curr_items'];
685
+ $total_items = $memcacheStats['total_items'];
686
+ $hits = ($memcacheStats['get_hits']==0) ? 1:$memcacheStats['get_hits'];
687
+ $misses = ($memcacheStats['get_misses']==0) ? 1:$memcacheStats['get_misses'];
688
+ $sets = $memcacheStats['cmd_set'];
689
+
690
+ $req_rate = sprintf("%.2f",($hits+$misses)/($time-$startTime));
691
+ $hit_rate = sprintf("%.2f",($hits)/($time-$startTime));
692
+ $miss_rate = sprintf("%.2f",($misses)/($time-$startTime));
693
+ $set_rate = sprintf("%.2f",($sets)/($time-$startTime));
694
+
695
+ echo <<< EOB
696
+ <div class="info div1"><h2>General Cache Information</h2>
697
+ <table cellspacing=0><tbody>
698
+ <tr class=tr-1><td class=td-0>PHP Version</td><td>$phpversion</td></tr>
699
+ EOB;
700
+ echo "<tr class=tr-0><td class=td-0>Memcached Host". ((count($MEMCACHE_SERVERS)>1) ? 's':'')."</td><td>";
701
+ $i=0;
702
+ if (!isset($_GET['singleout']) && count($MEMCACHE_SERVERS)>1){
703
+ foreach($MEMCACHE_SERVERS as $server){
704
+ echo ($i+1).'. <a href="'.$PHP_SELF.'&singleout='.$i++.'">'.$server.'</a><br/>';
705
+ }
706
+ }
707
+ else{
708
+ echo '1.'.$MEMCACHE_SERVERS[0];
709
+ }
710
+ if (isset($_GET['singleout'])){
711
+ echo '<a href="'.$PHP_SELF.'">(all servers)</a><br/>';
712
+ }
713
+ echo "</td></tr>\n";
714
+ echo "<tr class=tr-1><td class=td-0>Total Memcache Cache</td><td>".bsize($memcacheStats['limit_maxbytes'])."</td></tr>\n";
715
+
716
+ echo <<<EOB
717
+ </tbody></table>
718
+ </div>
719
+
720
+ <div class="info div1"><h2>Memcache Server Information</h2>
721
+ EOB;
722
+ foreach($MEMCACHE_SERVERS as $server){
723
+ echo '<table cellspacing=0><tbody>';
724
+ echo '<tr class=tr-1><td class=td-1>'.$server.'</td><td><a href="'.$PHP_SELF.'&server='.array_search($server,$MEMCACHE_SERVERS).'&op=6">[<b>Flush this server</b>]</a></td></tr>';
725
+ echo '<tr class=tr-0><td class=td-0>Start Time</td><td>',date(DATE_FORMAT,$memcacheStatsSingle[$server]['STAT']['time']-$memcacheStatsSingle[$server]['STAT']['uptime']),'</td></tr>';
726
+ echo '<tr class=tr-1><td class=td-0>Uptime</td><td>',duration($memcacheStatsSingle[$server]['STAT']['time']-$memcacheStatsSingle[$server]['STAT']['uptime']),'</td></tr>';
727
+ echo '<tr class=tr-0><td class=td-0>Memcached Server Version</td><td>'.$memcacheStatsSingle[$server]['STAT']['version'].'</td></tr>';
728
+ echo '<tr class=tr-1><td class=td-0>Used Cache Size</td><td>',bsize($memcacheStatsSingle[$server]['STAT']['bytes']),'</td></tr>';
729
+ echo '<tr class=tr-0><td class=td-0>Total Cache Size</td><td>',bsize($memcacheStatsSingle[$server]['STAT']['limit_maxbytes']),'</td></tr>';
730
+ echo '</tbody></table>';
731
+ }
732
+ echo <<<EOB
733
+
734
+ </div>
735
+ <div class="graph div3"><h2>Host Status Diagrams</h2>
736
+ <table cellspacing=0><tbody>
737
+ EOB;
738
+
739
+ $size='width='.(GRAPH_SIZE+50).' height='.(GRAPH_SIZE+10);
740
+ echo <<<EOB
741
+ <tr>
742
+ <td class=td-0>Cache Usage</td>
743
+ <td class=td-1>Hits &amp; Misses</td>
744
+ </tr>
745
+ EOB;
746
+
747
+ echo
748
+ graphics_avail() ?
749
+ '<tr>'.
750
+ "<td class=td-0><img alt=\"\" $size src=\"$PHP_SELF&IMG=1&".(isset($_GET['singleout'])? 'singleout='.$_GET['singleout'].'&':'')."$time\"></td>".
751
+ "<td class=td-1><img alt=\"\" $size src=\"$PHP_SELF&IMG=2&".(isset($_GET['singleout'])? 'singleout='.$_GET['singleout'].'&':'')."$time\"></td></tr>\n"
752
+ : "",
753
+ '<tr>',
754
+ '<td class=td-0><span class="green box">&nbsp;</span>Free: ',bsize($mem_avail).sprintf(" (%.1f%%)",$mem_avail*100/$mem_size),"</td>\n",
755
+ '<td class=td-1><span class="green box">&nbsp;</span>Hits: ',$hits.sprintf(" (%.1f%%)",$hits*100/($hits+$misses)),"</td>\n",
756
+ '</tr>',
757
+ '<tr>',
758
+ '<td class=td-0><span class="red box">&nbsp;</span>Used: ',bsize($mem_used ).sprintf(" (%.1f%%)",$mem_used *100/$mem_size),"</td>\n",
759
+ '<td class=td-1><span class="red box">&nbsp;</span>Misses: ',$misses.sprintf(" (%.1f%%)",$misses*100/($hits+$misses)),"</td>\n";
760
+ echo <<< EOB
761
+ </tr>
762
+ </tbody></table>
763
+ <br/>
764
+ <div class="info"><h2>Cache Information</h2>
765
+ <table cellspacing=0><tbody>
766
+ <tr class=tr-0><td class=td-0>Current Items(total)</td><td>$curr_items ($total_items)</td></tr>
767
+ <tr class=tr-1><td class=td-0>Hits</td><td>{$hits}</td></tr>
768
+ <tr class=tr-0><td class=td-0>Misses</td><td>{$misses}</td></tr>
769
+ <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate cache requests/second</td></tr>
770
+ <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate cache requests/second</td></tr>
771
+ <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate cache requests/second</td></tr>
772
+ <tr class=tr-0><td class=td-0>Set Rate</td><td>$set_rate cache requests/second</td></tr>
773
+ </tbody></table>
774
+ </div>
775
+
776
+ EOB;
777
+
778
+ break;
779
+
780
+ case 2: // variables
781
+
782
+ $m=0;
783
+ $cacheItems= getCacheItems();
784
+ $items = $cacheItems['items'];
785
+ $totals = $cacheItems['counts'];
786
+ $maxDump = MAX_ITEM_DUMP;
787
+ foreach($items as $server => $entries) {
788
+
789
+ echo <<< EOB
790
+
791
+ <div class="info"><table cellspacing=0><tbody>
792
+ <tr><th colspan="2">$server</th></tr>
793
+ <tr><th>Slab Id</th><th>Info</th></tr>
794
+ EOB;
795
+
796
+ foreach($entries as $slabId => $slab) {
797
+ $dumpUrl = $PHP_SELF.'&op=2&server='.(array_search($server,$MEMCACHE_SERVERS)).'&dumpslab='.$slabId;
798
+ echo
799
+ "<tr class=tr-$m>",
800
+ "<td class=td-0><center>",'<a href="',$dumpUrl,'">',$slabId,'</a>',"</center></td>",
801
+ "<td class=td-last><b>Item count:</b> ",$slab['number'],'<br/><b>Age:</b>',duration($time-$slab['age']),'<br/> <b>Evicted:</b>',((isset($slab['evicted']) && $slab['evicted']==1)? 'Yes':'No');
802
+ if ((isset($_GET['dumpslab']) && $_GET['dumpslab']==$slabId) && (isset($_GET['server']) && $_GET['server']==array_search($server,$MEMCACHE_SERVERS))){
803
+ echo "<br/><b>Items: item</b><br/>";
804
+ $items = dumpCacheSlab($server,$slabId,$slab['number']);
805
+ // maybe someone likes to do a pagination here :)
806
+ $i=1;
807
+ foreach($items['ITEM'] as $itemKey=>$itemInfo){
808
+ $itemInfo = trim($itemInfo,'[ ]');
809
+
810
+
811
+ echo '<a href="',$PHP_SELF,'&op=4&server=',(array_search($server,$MEMCACHE_SERVERS)),'&key=',base64_encode($itemKey).'">',$itemKey,'</a>';
812
+ if ($i++ % 10 == 0) {
813
+ echo '<br/>';
814
+ }
815
+ elseif ($i!=$slab['number']+1){
816
+ echo ',';
817
+ }
818
+ }
819
+ }
820
+
821
+ echo "</td></tr>";
822
+ $m=1-$m;
823
+ }
824
+ echo <<<EOB
825
+ </tbody></table>
826
+ </div><hr/>
827
+ EOB;
828
+ }
829
+ break;
830
+
831
+ break;
832
+
833
+ case 4: //item dump
834
+ if (!isset($_GET['key']) || !isset($_GET['server'])){
835
+ echo "No key set!";
836
+ break;
837
+ }
838
+ // I'm not doing anything to check the validity of the key string.
839
+ // probably an exploit can be written to delete all the files in key=base64_encode("\n\r delete all").
840
+ // somebody has to do a fix to this.
841
+ $theKey = htmlentities(base64_decode($_GET['key']));
842
+
843
+ $theserver = $MEMCACHE_SERVERS[(int)$_GET['server']];
844
+ list($h,$p) = explode(':',$theserver);
845
+ $r = sendMemcacheCommand($h,$p,'get '.$theKey);
846
+ echo <<<EOB
847
+ <div class="info"><table cellspacing=0><tbody>
848
+ <tr><th>Server<th>Key</th><th>Value</th><th>Delete</th></tr>
849
+ EOB;
850
+ echo "<tr><td class=td-0>",$theserver,"</td><td class=td-0>",$theKey,
851
+ " <br/>flag:",$r['VALUE'][$theKey]['stat']['flag'],
852
+ " <br/>Size:",bsize($r['VALUE'][$theKey]['stat']['size']),
853
+ "</td><td>",chunk_split($r['VALUE'][$theKey]['value'],40),"</td>",
854
+ '<td><a href="',$PHP_SELF,'&op=5&server=',(int)$_GET['server'],'&key=',base64_encode($theKey),"\">Delete</a></td>","</tr>";
855
+ echo <<<EOB
856
+ </tbody></table>
857
+ </div><hr/>
858
+ EOB;
859
+ break;
860
+ case 5: // item delete
861
+ if (!isset($_GET['key']) || !isset($_GET['server'])){
862
+ echo "No key set!";
863
+ break;
864
+ }
865
+ $theKey = htmlentities(base64_decode($_GET['key']));
866
+ $theserver = $MEMCACHE_SERVERS[(int)$_GET['server']];
867
+ list($h,$p) = explode(':',$theserver);
868
+ $r = sendMemcacheCommand($h,$p,'delete '.$theKey);
869
+ echo 'Deleting '.$theKey.':'.$r;
870
+ break;
871
+
872
+ case 6: // flush server
873
+ $theserver = $MEMCACHE_SERVERS[(int)$_GET['server']];
874
+ $r = flushServer($theserver);
875
+ echo 'Flush '.$theserver.":".$r;
876
+ break;
877
+ }
878
+ echo getFooter();
879
+
880
+ ?>
tools/phpinfo.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ phpinfo();
w3-total-cache-config-default.php CHANGED
@@ -79,7 +79,7 @@ return array(
79
  'localhost:11211'
80
  ),
81
  'minify.rewrite' => true,
82
- 'minify.logger' => false,
83
  'minify.cache.path' => '',
84
  'minify.cache.locking' => true,
85
  'minify.docroot' => '',
@@ -96,6 +96,7 @@ return array(
96
  )
97
  ),
98
  'minify.lifetime' => 3600,
 
99
  'minify.html.enable' => true,
100
  'minify.html.reject.admin' => true,
101
  'minify.html.strip.crlf' => false,
79
  'localhost:11211'
80
  ),
81
  'minify.rewrite' => true,
82
+ 'minify.logging' => true,
83
  'minify.cache.path' => '',
84
  'minify.cache.locking' => true,
85
  'minify.docroot' => '',
96
  )
97
  ),
98
  'minify.lifetime' => 3600,
99
+ 'minify.upload' => true,
100
  'minify.html.enable' => true,
101
  'minify.html.reject.admin' => true,
102
  'minify.html.strip.crlf' => false,
w3-total-cache.php CHANGED
@@ -2,7 +2,7 @@
2
  /*
3
  Plugin Name: W3 Total Cache
4
  Description: Dramatically improve the user experience of your blog. Add transparent page caching, database caching, minify and content delivery network (CDN) functionality and more to WordPress.
5
- Version: 0.7.5.1
6
  Plugin URI: http://www.w3-edge.com/wordpress-plugins/w3-total-cache/
7
  Author: Frederick Townes
8
  Author URI: http://www.linkedin.com/in/w3edge
2
  /*
3
  Plugin Name: W3 Total Cache
4
  Description: Dramatically improve the user experience of your blog. Add transparent page caching, database caching, minify and content delivery network (CDN) functionality and more to WordPress.
5
+ Version: 0.7.5.2
6
  Plugin URI: http://www.w3-edge.com/wordpress-plugins/w3-total-cache/
7
  Author: Frederick Townes
8
  Author URI: http://www.linkedin.com/in/w3edge
wp-content/advanced-cache.php CHANGED
@@ -12,7 +12,10 @@ if (! is_dir(W3TC_DIR) || ! file_exists(W3TC_DIR . '/inc/define.php')) {
12
  }
13
 
14
  require_once W3TC_DIR . '/inc/define.php';
15
- require_once W3TC_DIR . '/lib/W3/PgCache.php';
16
 
17
- $w3_pgcache = W3_PgCache::instance();
18
- $w3_pgcache->process();
 
 
 
 
12
  }
13
 
14
  require_once W3TC_DIR . '/inc/define.php';
 
15
 
16
+ if (file_exists(W3TC_CONFIG_PATH)) {
17
+ require_once W3TC_DIR . '/lib/W3/PgCache.php';
18
+
19
+ $w3_pgcache = W3_PgCache::instance();
20
+ $w3_pgcache->process();
21
+ }
wp-content/db.php CHANGED
@@ -12,6 +12,11 @@ if (! is_dir(W3TC_DIR) || ! file_exists(W3TC_DIR . '/inc/define.php')) {
12
  }
13
 
14
  require_once W3TC_DIR . '/inc/define.php';
15
- require_once W3TC_DIR . '/lib/W3/Db.php';
16
 
17
- $wpdb = W3_Db::instance();
 
 
 
 
 
 
12
  }
13
 
14
  require_once W3TC_DIR . '/inc/define.php';
 
15
 
16
+ if (file_exists(W3TC_CONFIG_PATH)) {
17
+ require_once W3TC_DIR . '/lib/W3/Db.php';
18
+
19
+ $wpdb = W3_Db::instance();
20
+ } else {
21
+ require_once ABSPATH . WPINC . '/wp-db.php';
22
+ }
wp-content/w3tc-cache/index.php CHANGED
@@ -19,7 +19,10 @@ if (! is_dir(W3TC_DIR) || ! file_exists(W3TC_DIR . '/inc/define.php')) {
19
  }
20
 
21
  require_once W3TC_DIR . '/inc/define.php';
22
- require_once W3TC_DIR . '/lib/W3/Minify.php';
23
 
24
- $w3_minify = W3_Minify::instance();
25
- $w3_minify->process();
 
 
 
 
19
  }
20
 
21
  require_once W3TC_DIR . '/inc/define.php';
 
22
 
23
+ if (file_exists(W3TC_CONFIG_PATH)) {
24
+ require_once W3TC_DIR . '/lib/W3/Minify.php';
25
+
26
+ $w3_minify = W3_Minify::instance();
27
+ $w3_minify->process();
28
+ }