PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/components/com_virtuemart/fetchscript.php

https://bitbucket.org/dgough/annamaria-daneswood-25102012
PHP | 258 lines | 185 code | 31 blank | 42 comment | 43 complexity | 813f17d856b9d32cfd5468ebd87c58e7 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * This file is used to send gzipped Javascripts and Stylesheets to the browser
  4. *
  5. * It expects three parameters:
  6. *
  7. * gzip (can be 1 or 0, for yes or no; default: 0)
  8. * subdir[INDEX] (relative directory from /components/com_virtuemart/js)
  9. * file[INDEX] (filename only)
  10. * where INDEX is the actual number of the file to be included, so you can include multiple scripts at a time
  11. *
  12. * @version $Id: fetchscript.php 1367 2008-04-10 19:30:20Z soeren_nb $
  13. * @package VirtueMart
  14. * @subpackage core
  15. * @copyright Copyright (C) 2006-2007 soeren - All rights reserved.
  16. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
  17. * VirtueMart is free software. This version may have been modified pursuant
  18. * to the GNU General Public License, and as distributed it includes or
  19. * is derivative of works licensed under the GNU General Public License or
  20. * other free or open source software licenses.
  21. * See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
  22. *
  23. * http://virtuemart.net
  24. */
  25. /**
  26. * Initialise GZIP
  27. * @author Mambo / Joomla Project
  28. */
  29. function initGzip() {
  30. global $do_gzip_compress;
  31. $gzip = isset( $_GET['gzip'] ) ? (boolean)$_GET['gzip'] : false;
  32. $do_gzip_compress = FALSE;
  33. if ($gzip) {
  34. $phpver = phpversion();
  35. $useragent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '';
  36. $canZip = isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ? $_SERVER['HTTP_ACCEPT_ENCODING'] : '';
  37. $gzip_check = 0;
  38. $zlib_check = 0;
  39. $gz_check = 0;
  40. $zlibO_check = 0;
  41. $sid_check = 0;
  42. if ( strpos( $canZip, 'gzip' ) !== false) {
  43. $gzip_check = 1;
  44. }
  45. if ( extension_loaded( 'zlib' ) ) {
  46. $zlib_check = 1;
  47. }
  48. if ( function_exists('ob_gzhandler') ) {
  49. $gz_check = 1;
  50. }
  51. if ( ini_get('zlib.output_compression') ) {
  52. $zlibO_check = 1;
  53. }
  54. if ( $phpver >= '4.0.4pl1' && ( strpos($useragent,'compatible') !== false || strpos($useragent,'Gecko') !== false ) ) {
  55. // Check for gzip header or norton internet securities
  56. if ( ( $gzip_check || isset( $_SERVER['---------------']) ) && $zlib_check && $gz_check && !$zlibO_check ) {
  57. // You cannot specify additional output handlers if
  58. // zlib.output_compression is activated here
  59. ob_start( 'ob_gzhandler' );
  60. return;
  61. }
  62. } else if ( $phpver > '4.0' ) {
  63. if ( $gzip_check ) {
  64. if ( $zlib_check ) {
  65. $do_gzip_compress = TRUE;
  66. ob_start();
  67. ob_implicit_flush(0);
  68. header( 'Content-Encoding: gzip' );
  69. return;
  70. }
  71. }
  72. }
  73. }
  74. ob_start();
  75. }
  76. /**
  77. * Perform GZIP
  78. * @author Mambo / Joomla! project
  79. */
  80. function doGzip() {
  81. global $do_gzip_compress;
  82. if ( $do_gzip_compress ) {
  83. /**
  84. *Borrowed from php.net!
  85. */
  86. $gzip_contents = ob_get_contents();
  87. ob_end_clean();
  88. $gzip_size = strlen($gzip_contents);
  89. $gzip_crc = crc32($gzip_contents);
  90. $gzip_contents = gzcompress($gzip_contents, 9);
  91. $gzip_contents = substr($gzip_contents, 0, strlen($gzip_contents) - 4);
  92. echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
  93. echo $gzip_contents;
  94. echo pack('V', $gzip_crc);
  95. echo pack('V', $gzip_size);
  96. } else {
  97. ob_end_flush();
  98. }
  99. }
  100. function cssUrl( $ref, $subdir ) {
  101. $ref = str_replace( "'", '', stripslashes( trim($ref) ));
  102. $ref = str_replace( '"', '', $ref);
  103. if( $subdir[0] == '/' ) {
  104. $subdir = substr( $subdir, 1 );
  105. }
  106. return 'url( "'. $subdir.'/'.$ref.'" )';
  107. }
  108. /**
  109. * Checks and sets HTTP headers for conditional HTTP requests
  110. * Borrowed from DokuWiki (/lib/exe/fetch.php)
  111. * @author Simon Willison <swillison@gmail.com>
  112. * @link http://simon.incutio.com/archive/2003/04/23/conditionalGet
  113. */
  114. function http_conditionalRequest($timestamp){
  115. // A PHP implementation of conditional get, see
  116. // http://fishbowl.pastiche.org/archives/001132.html
  117. $last_modified = gmdate( 'D, d M Y H:i:s', $timestamp ) . ' GMT';
  118. $etag = '"'.md5($last_modified).'"';
  119. // Send the headers
  120. header("Last-Modified: $last_modified");
  121. header("ETag: $etag");
  122. // See if the client has provided the required headers
  123. $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ?
  124. stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) :
  125. false;
  126. $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ?
  127. stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) :
  128. false;
  129. if (!$if_modified_since && !$if_none_match) {
  130. return;
  131. }
  132. // At least one of the headers is there - check them
  133. if ($if_none_match && $if_none_match != $etag) {
  134. return; // etag is there but doesn't match
  135. }
  136. if ($if_modified_since && $if_modified_since != $last_modified) {
  137. return; // if-modified-since is there but doesn't match
  138. }
  139. // Nothing has changed since their last request - serve a 304 and exit
  140. header('HTTP/1.0 304 Not Modified');
  141. exit;
  142. }
  143. initGzip();
  144. $base_dir = dirname( __FILE__ );
  145. $subdirs = @$_GET['subdir'];
  146. if( !is_array( $subdirs ) && !empty( $subdirs )) {
  147. $subdirs = array( $subdirs );
  148. }
  149. $files = @$_GET['file'];
  150. if( !is_array( $files ) && !empty( $files )) {
  151. $files = array( $files );
  152. }
  153. if( empty( $files ) || sizeof($files) != sizeof( $subdirs )) {
  154. header("HTTP/1.0 400 Bad Request");
  155. echo 'Bad request';
  156. exit;
  157. }
  158. $countFiles = sizeof($files);
  159. $newest_mdate = 0;
  160. for( $i = 0; $i < $countFiles; $i++ ) {
  161. $file = $files[$i];
  162. $subdir = $subdirs[$i];
  163. $dir = realpath( $base_dir . '/' . $subdir );
  164. $file = $dir . '/' . basename( $file );
  165. if( !file_exists( $file ) || !stristr( $dir, $base_dir )) {
  166. if( $countFiles == 1 ) {
  167. header("HTTP/1.0 404 Not Found");
  168. echo 'Not Found';
  169. exit;
  170. }
  171. continue;
  172. }
  173. $newest_mdate = max( filemtime( $file ), $newest_mdate );
  174. }
  175. // This function quits the page load if the browser has a cached version of the requested script.
  176. // It then returns a 304 Not Modified header
  177. http_conditionalRequest( $newest_mdate );
  178. // here we need to send the script or stylesheet
  179. $processed_files = 0;
  180. for( $i = 0; $i < $countFiles; $i++ ) {
  181. $file = $files[$i];
  182. $subdir = $subdirs[$i];
  183. $dir = realpath( $base_dir . '/' . $subdir );
  184. $file = $dir . '/' . basename( $file );
  185. if( !file_exists( $file ) || !stristr( $dir, $base_dir ) || !is_readable( $file )) {
  186. continue;
  187. }
  188. $processed_files++;
  189. $fileinfo = pathinfo( $file );
  190. switch ( $fileinfo['extension']) {
  191. case 'css':
  192. $mime_type = 'text/css';
  193. header( 'Content-Type: '.$mime_type.';');
  194. $css = implode( '', file( $file ));
  195. $str_css = preg_replace("/url\((.+?)\)/ie","cssUrl('\\1', '$subdir')", $css);
  196. echo $str_css;
  197. break;
  198. case 'js':
  199. $mime_type = 'text/javascript';
  200. header( 'Content-Type: '.$mime_type.';');
  201. readfile( $file );
  202. break;
  203. default:
  204. continue;
  205. }
  206. }
  207. if( $processed_files == 0 ) {
  208. if( !file_exists( $file ) ) {
  209. header("HTTP/1.0 404 Not Found");
  210. echo 'Not Found';
  211. exit;
  212. }
  213. if( !is_readable( $file ) ) {
  214. header("HTTP/1.0 500 Internal Server Error");
  215. echo "Could not read ".basename($file)." - bad permissions?";
  216. exit;
  217. }
  218. }
  219. // Tell the user agent to cache this script/stylesheet for a week
  220. $age = 604800;
  221. header( 'Expires: '.gmdate( 'D, d M Y H:i:s', time()+ $age ) . ' GMT' );
  222. header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s', @filemtime( $file ) ) . ' GMT' );
  223. header( 'Cache-Control: public, max-age='.$age.', must-revalidate, post-check=0, pre-check=0' );
  224. header( 'Pragma: public' );
  225. doGzip();
  226. exit;
  227. ?>