PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/w3-total-cache/lib/W3/Cdn/Base.php

https://bitbucket.org/openfarmtech/weblog-content
PHP | 465 lines | 223 code | 68 blank | 174 comment | 24 complexity | b87a1a5b68ba54543d57398fd01284a3 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0, LGPL-2.0, LGPL-3.0, BSD-3-Clause, GPL-3.0, LGPL-2.1, AGPL-3.0, CC-BY-SA-3.0
  1. <?php
  2. /**
  3. * W3 CDN Base class
  4. */
  5. if (!defined('W3TC_CDN_RESULT_HALT')) {
  6. define('W3TC_CDN_RESULT_HALT', -1);
  7. }
  8. if (!defined('W3TC_CDN_RESULT_ERROR')) {
  9. define('W3TC_CDN_RESULT_ERROR', 0);
  10. }
  11. if (!defined('W3TC_CDN_RESULT_OK')) {
  12. define('W3TC_CDN_RESULT_OK', 1);
  13. }
  14. /**
  15. * Class W3_Cdn_Base
  16. */
  17. class W3_Cdn_Base
  18. {
  19. /**
  20. * CDN Configuration
  21. *
  22. * @var array
  23. */
  24. var $_config = array();
  25. /**
  26. * Cache config
  27. * @var array
  28. */
  29. var $cache_config = array();
  30. /**
  31. * PHP5 Constructor
  32. *
  33. * @param array $config
  34. */
  35. function __construct($config)
  36. {
  37. $this->_config = $config;
  38. }
  39. /**
  40. * PHP4 Constructor
  41. *
  42. * @param array $config
  43. */
  44. function W3_Cdn_Base($config)
  45. {
  46. $this->__construct($config);
  47. }
  48. /**
  49. * Upload files to CDN
  50. *
  51. * @param array $files
  52. * @param array $results
  53. * @param boolean $force_rewrite
  54. * @return boolean
  55. */
  56. function upload($files, &$results, $force_rewrite = false)
  57. {
  58. $results = $this->get_results($files, W3TC_CDN_RESULT_HALT, 'Not implemented.');
  59. return false;
  60. }
  61. /**
  62. * Delete files from CDN
  63. *
  64. * @param array $files
  65. * @param array $results
  66. * @return boolean
  67. */
  68. function delete($files, &$results)
  69. {
  70. $results = $this->get_results($files, W3TC_CDN_RESULT_HALT, 'Not implemented.');
  71. return false;
  72. }
  73. /**
  74. * Purges URLs from CDN
  75. *
  76. * @param array $files
  77. * @param array $results
  78. * @return boolean
  79. */
  80. function purge($files, &$results)
  81. {
  82. return $this->upload($files, $results, true);
  83. }
  84. /**
  85. * Test CDN server
  86. *
  87. * @param string $error
  88. * @return boolean
  89. */
  90. function test(&$error)
  91. {
  92. if (!$this->_test_domains($error)) {
  93. return false;
  94. }
  95. return true;
  96. }
  97. /**
  98. * Create bucket / container for some CDN engines
  99. *
  100. * @param string $container_id
  101. * @param string $error
  102. * @return boolean
  103. */
  104. function create_container(&$container_id, &$error)
  105. {
  106. $error = 'Not implemented.';
  107. return false;
  108. }
  109. /**
  110. * Returns first domain
  111. *
  112. * @return string
  113. */
  114. function get_domain()
  115. {
  116. $domains = $this->get_domains();
  117. if (count($domains)) {
  118. return current($domains);
  119. }
  120. return false;
  121. }
  122. /**
  123. * Returns array of CDN domains
  124. *
  125. * @return array
  126. */
  127. function get_domains()
  128. {
  129. return array();
  130. }
  131. /**
  132. * Returns via string
  133. *
  134. * @return string
  135. */
  136. function get_via()
  137. {
  138. $domain = $this->get_domain();
  139. if ($domain) {
  140. return $domain;
  141. }
  142. return 'N/A';
  143. }
  144. /**
  145. * Formats object URL
  146. *
  147. * @param string $path
  148. * @return string
  149. */
  150. function format_url($path)
  151. {
  152. $domains = $this->get_domains();
  153. $count = count($domains);
  154. if ($count) {
  155. switch (true) {
  156. /**
  157. * Reserved CSS
  158. */
  159. case (isset($domains[0]) && $this->_is_css($path)):
  160. $host = $domains[0];
  161. break;
  162. /**
  163. * Reserved JS in head
  164. */
  165. case (isset($domains[1]) && $this->_is_js($path)):
  166. $host = $domains[1];
  167. break;
  168. /**
  169. * Reserved JS after body
  170. */
  171. case (isset($domains[2]) && $this->_is_js_body($path)):
  172. $host = $domains[2];
  173. break;
  174. /**
  175. * Reserved JS before /body
  176. */
  177. case (isset($domains[3]) && $this->_is_js_footer($path)):
  178. $host = $domains[3];
  179. break;
  180. default:
  181. if ($count > 4) {
  182. $host = $this->_get_host(array_slice($domains, 4), $path);
  183. } else {
  184. $host = $this->_get_host($domains, $path);
  185. }
  186. }
  187. $url = sprintf('%s://%s/%s', (w3_is_https() ? 'https' : 'http'), $host, $path);
  188. return $url;
  189. }
  190. return false;
  191. }
  192. /**
  193. * Returns results
  194. *
  195. * @param array $files
  196. * @param integer $result
  197. * @param string $error
  198. * @return array
  199. */
  200. function get_results($files, $result = W3TC_CDN_RESULT_OK, $error = 'OK')
  201. {
  202. $results = array();
  203. foreach ($files as $local_path => $remote_path) {
  204. $results[] = $this->get_result($local_path, $remote_path, $result, $error);
  205. }
  206. return $results;
  207. }
  208. /**
  209. * Returns file process result
  210. *
  211. * @param string $local_path
  212. * @param string $remote_path
  213. * @param integer $result
  214. * @param string $error
  215. * @return array
  216. */
  217. function get_result($local_path, $remote_path, $result = W3TC_CDN_RESULT_OK, $error = 'OK')
  218. {
  219. return array(
  220. 'local_path' => $local_path,
  221. 'remote_path' => $remote_path,
  222. 'result' => $result,
  223. 'error' => $error
  224. );
  225. }
  226. /**
  227. * Returns headers for file
  228. *
  229. * @param string $file
  230. * @return array
  231. */
  232. function get_headers($file)
  233. {
  234. $mime_type = w3_get_mime_type($file);
  235. $last_modified = time();
  236. $headers = array(
  237. 'Content-Type' => $mime_type,
  238. 'Last-Modified' => w3_http_date($last_modified)
  239. );
  240. if (isset($this->cache_config[$mime_type])) {
  241. if ($this->cache_config[$mime_type]['etag']) {
  242. $headers['Etag'] = @md5_file($file);
  243. }
  244. if ($this->cache_config[$mime_type]['w3tc']) {
  245. $headers['X-Powered-By'] = W3TC_POWERED_BY;
  246. }
  247. if ($this->cache_config[$mime_type]['lifetime']) {
  248. $headers['Expires'] = w3_http_date($last_modified + $this->cache_config[$mime_type]['lifetime']);
  249. }
  250. switch ($this->cache_config[$mime_type]['cache_control']) {
  251. case 'cache':
  252. $headers = array_merge($headers, array(
  253. 'Pragma' => 'public',
  254. 'Cache-Control' => 'public'
  255. ));
  256. break;
  257. case 'cache_validation':
  258. $headers = array_merge($headers, array(
  259. 'Pragma' => 'public',
  260. 'Cache-Control' => 'public, must-revalidate, proxy-revalidate'
  261. ));
  262. break;
  263. case 'cache_noproxy':
  264. $headers = array_merge($headers, array(
  265. 'Pragma' => 'public',
  266. 'Cache-Control' => 'public, must-revalidate'
  267. ));
  268. break;
  269. case 'cache_maxage':
  270. $headers = array_merge($headers, array(
  271. 'Pragma' => 'public',
  272. 'Cache-Control' => 'max-age=' . $this->cache_config[$mime_type]['lifetime'] . ', public, must-revalidate, proxy-revalidate'
  273. ));
  274. break;
  275. case 'no_cache':
  276. $headers = array_merge($headers, array(
  277. 'Pragma' => 'no-cache',
  278. 'Cache-Control' => 'max-age=0, private, no-store, no-cache, must-revalidate'
  279. ));
  280. break;
  281. }
  282. }
  283. return $headers;
  284. }
  285. /**
  286. * Use gzip compression only for text-based files
  287. *
  288. * @param string $file
  289. * @return boolean
  290. */
  291. function may_gzip($file)
  292. {
  293. /**
  294. * Remove query string
  295. */
  296. $file = preg_replace('~\?.*$~', '', $file);
  297. /**
  298. * Check by file extension
  299. */
  300. if (preg_match('~\.(ico|js|css|xml|xsd|xsl|svg|htm|html|txt)$~i', $file)) {
  301. return true;
  302. }
  303. return false;
  304. }
  305. /**
  306. * Test domains
  307. *
  308. * @param string $error
  309. * @return boolean
  310. */
  311. function _test_domains(&$error)
  312. {
  313. $domains = $this->get_domains();
  314. if (!count($domains)) {
  315. $error = 'Empty domains / CNAMEs list.';
  316. return false;
  317. }
  318. foreach ($domains as $domain) {
  319. if ($domain && gethostbyname($domain) === $domain) {
  320. $error = sprintf('Unable to resolve domain: %s.', $domain);
  321. return false;
  322. }
  323. }
  324. return true;
  325. }
  326. /**
  327. * Check if css file
  328. *
  329. * @param string $path
  330. * @return boolean
  331. */
  332. function _is_css($path)
  333. {
  334. return preg_match('~[a-z0-9\-_]+\.include\.[0-9]+\.css$~', $path);
  335. }
  336. /**
  337. * Check if JS file in heeader
  338. *
  339. * @param string $path
  340. * @return boolean
  341. */
  342. function _is_js($path)
  343. {
  344. return preg_match('~[a-z0-9\-_]+\.include(-nb)?\.[0-9]+\.js$~', $path);
  345. }
  346. /**
  347. * Check if JS file after body
  348. *
  349. * @param string $path
  350. * @return boolean
  351. */
  352. function _is_js_body($path)
  353. {
  354. return preg_match('~[a-z0-9\-_]+\.include-body(-nb)?\.[0-9]+\.js$~', $path);
  355. }
  356. /**
  357. * Check if JS file before /body
  358. *
  359. * @param string $path
  360. * @return boolean
  361. */
  362. function _is_js_footer($path)
  363. {
  364. return preg_match('~[a-z0-9\-_]+\.include-footer(-nb)?\.[0-9]+\.js$~', $path);
  365. }
  366. /**
  367. * Returns host for path
  368. *
  369. * @param array $domains
  370. * @param string $path
  371. * @return string
  372. */
  373. function _get_host($domains, $path)
  374. {
  375. $count = count($domains);
  376. if ($count) {
  377. /**
  378. * Use for equal URLs same host to allow caching by browser
  379. */
  380. $hash = $this->_get_hash($path);
  381. $host = $domains[$hash % $count];
  382. return $host;
  383. }
  384. return false;
  385. }
  386. /**
  387. * Returns integer hash for key
  388. *
  389. * @param string $key
  390. * @return integer
  391. */
  392. function _get_hash($key)
  393. {
  394. $hash = abs(crc32($key));
  395. return $hash;
  396. }
  397. }