PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Quản lý website trường trung học phổ thông PHP/lc1/CJzip.php

https://gitlab.com/phamngsinh/baitaplon_sinhvien
PHP | 357 lines | 266 code | 32 blank | 59 comment | 39 complexity | b392da161e9b33310f997da285ddb027 MD5 | raw file
  1. <?php
  2. /**
  3. * @Project NUKEVIET 3.0
  4. * @Author VINADES.,JSC (contact@vinades.vn)
  5. * @Copyright (C) 2010 VINADES.,JSC. All rights reserved
  6. * @Createdate 23/11/2010, 20:46
  7. */
  8. /**
  9. * CJzip
  10. *
  11. * @package
  12. * @author NUKEVIET 3.0
  13. * @copyright VINADES.,JSC
  14. * @version 2010
  15. * @access public
  16. */
  17. class CJzip
  18. {
  19. private $is_gzip = false;
  20. private $getName = "file";
  21. private $file = array();
  22. private $maxAge = 2592000;
  23. private $encoding = 'none';
  24. private $currenttime;
  25. private $siteRoot;
  26. private $base_siteurl;
  27. private $isOptimized = false;
  28. private $root = false;
  29. private $cssImgNewPath = "";
  30. /**
  31. * CJzip::__construct()
  32. *
  33. * @return
  34. */
  35. public function __construct()
  36. {
  37. if ( ! isset( $_GET[$this->getName] ) )
  38. {
  39. $this->browseInfo( 404 );
  40. }
  41. if ( extension_loaded( 'zlib' ) and ini_get( 'output_handler' ) == "" )
  42. {
  43. if ( strtolower( ini_get( 'zlib.output_compression' ) ) == "on" or ini_get( 'zlib.output_compression' ) == 1 )
  44. {
  45. $disable_functions = ( ini_get( "disable_functions" ) != "" and ini_get( "disable_functions" ) != false ) ? array_map( 'trim', preg_split( "/[\s,]+/", ini_get( "disable_functions" ) ) ) : array();
  46. if ( extension_loaded( 'suhosin' ) )
  47. {
  48. $disable_functions = array_merge( $disable_functions, array_map( 'trim', preg_split( "/[\s,]+/", ini_get( "suhosin.executor.func.blacklist" ) ) ) );
  49. }
  50. $ini_set_support = ( function_exists( 'ini_set' ) and ! in_array( 'ini_set', $disable_functions ) ) ? true : false;
  51. if ( $ini_set_support )
  52. {
  53. ini_set( 'zlib.output_compression_level', 6 );
  54. }
  55. }
  56. else
  57. {
  58. $this->is_gzip = true;
  59. }
  60. }
  61. $this->siteRoot = str_replace( '\\', '/', realpath( dirname( __file__ ) ) );
  62. $base_siteurl = pathinfo( $_SERVER['PHP_SELF'], PATHINFO_DIRNAME );
  63. if ( $base_siteurl == '\\' or $base_siteurl == '/' ) $base_siteurl = '';
  64. if ( ! empty( $base_siteurl ) ) $base_siteurl = str_replace( '\\', '/', $base_siteurl );
  65. if ( ! empty( $base_siteurl ) ) $base_siteurl = preg_replace( "/[\/]+$/", '', $base_siteurl );
  66. if ( ! empty( $base_siteurl ) ) {
  67. $base_siteurl = preg_replace( "/^[\/]*(.*)$/", '/\\1', $base_siteurl );
  68. $base_siteurl = preg_replace( "#/index\.php(.*)$#", '', $base_siteurl );
  69. }
  70. $this->base_siteurl = $base_siteurl . '/';
  71. $filename = $_GET[$this->getName];
  72. if ( preg_match( "/^\//", $filename ) ) $filename = preg_replace( "#^" . $this->base_siteurl . "#", "", $filename );
  73. $this->file['path'] = $this->siteRoot . '/' . $filename;
  74. $this->file['lastmod'] = @filemtime( $this->file['path'] );
  75. if ( ! $this->file['lastmod'] )
  76. {
  77. $this->browseInfo( 404 );
  78. }
  79. unset( $matches );
  80. preg_match( "/(.*?)\.(css|js)$/", $this->file['path'], $matches );
  81. if ( ! $matches )
  82. {
  83. $this->browseInfo( 403 );
  84. }
  85. $this->file['ext'] = $matches[2];
  86. $this->file['contenttype'] = ( $this->file['ext'] == "css" ) ? "css" : "javascript";
  87. if ( preg_match( "/\.opt$/", $matches[1] ) )
  88. {
  89. $this->isOptimized = true;
  90. }
  91. $this->currenttime = time();
  92. if ( isset( $_GET['r'] ) and $_GET['r'] == 1 )
  93. {
  94. $this->root = true;
  95. $this->file['md5file'] = md5( $this->file['path'] . "_root" );
  96. }
  97. else
  98. {
  99. $this->file['md5file'] = md5( $this->file['path'] );
  100. }
  101. $this->cssImgNewPath = str_replace( '\\', '/', dirname( $filename ) ) . "/";
  102. }
  103. /**
  104. * CJzip::browseInfo()
  105. *
  106. * @param mixed $num
  107. * @return
  108. */
  109. public function browseInfo( $num )
  110. {
  111. switch ( $num )
  112. {
  113. case 304:
  114. $info = "HTTP/1.1 304 Not Modified";
  115. break;
  116. case 403:
  117. $info = "HTTP/1.1 403 Forbidden";
  118. break;
  119. default:
  120. $info = "HTTP/1.1 404 Not Found";
  121. }
  122. header( $info );
  123. header( 'Content-Length: 0' );
  124. exit();
  125. }
  126. /**
  127. * CJzip::is_notModified()
  128. *
  129. * @param mixed $hash
  130. * @return
  131. */
  132. private function is_notModified( $hash )
  133. {
  134. return ( isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) && stripslashes( $_SERVER['HTTP_IF_NONE_MATCH'] ) == '"' . $hash . '"' );
  135. }
  136. /**
  137. * CJzip::check_encode()
  138. *
  139. * @return
  140. */
  141. private function check_encode()
  142. {
  143. if ( ! $this->is_gzip ) return ( 'none' );
  144. if ( ! function_exists( 'gzencode' ) ) return ( 'none' );
  145. $encoding = strstr( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip' ) ? 'gzip' : ( strstr( $_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate' ) ? 'deflate' : 'none' );
  146. if ( $encoding != 'none' )
  147. {
  148. unset( $matches );
  149. if ( ! strstr( $_SERVER['HTTP_USER_AGENT'], 'Opera' ) && preg_match( '/^Mozilla\/4\.0 \(compatible; MSIE ([0-9]\.[0-9])/i', $_SERVER['HTTP_USER_AGENT'], $matches ) )
  150. {
  151. $version = floatval( $matches[1] );
  152. if ( $version < 6 || ( $version == 6 && ! strstr( $_SERVER['HTTP_USER_AGENT'], 'EV1' ) ) ) $encoding = 'none';
  153. }
  154. }
  155. return $encoding;
  156. }
  157. /**
  158. * CJzip::loadData()
  159. *
  160. * @return
  161. */
  162. private function loadData()
  163. {
  164. $data = file_get_contents( $this->file['path'] );
  165. if ( ! $this->isOptimized )
  166. {
  167. $data = ( $this->file['contenttype'] == 'css' ) ? $this->compress_css( $data ) : $this->compress_javascript( $data );
  168. }
  169. if ( $this->file['contenttype'] == 'css' and $this->root == true )
  170. {
  171. $data = preg_replace_callback( "/url\(([^\)]+)\)/", array( $this, 'changeCssURL' ), $data );
  172. }
  173. if ( $this->encoding != 'none' )
  174. {
  175. $data = gzencode( $data, 6, $this->encoding == 'gzip' ? FORCE_GZIP : FORCE_DEFLATE );
  176. header( "Content-Encoding: " . $this->encoding );
  177. header( 'Vary: Accept-Encoding' );
  178. }
  179. header( "Content-Type: text/" . $this->file['contenttype'] . "; charset=utf-8" );
  180. header( 'Cache-Control: public; max-age=' . $this->maxAge );
  181. header( 'Last-Modified: ' . gmdate( "D, d M Y H:i:s", $this->file['lastmod'] ) . " GMT" );
  182. header( "expires: " . gmdate( "D, d M Y H:i:s", $this->currenttime + $this->maxAge ) . " GMT" );
  183. echo $data;
  184. exit();
  185. }
  186. /**
  187. * CJzip::commentCB()
  188. *
  189. * @param mixed $m
  190. * @return
  191. */
  192. private function commentCB( $m )
  193. {
  194. $hasSurroundingWs = ( trim( $m[0] ) !== $m[1] );
  195. $m = $m[1];
  196. if ( $m === 'keep' )
  197. {
  198. return '/**/';
  199. }
  200. if ( $m === '" "' )
  201. {
  202. return '/*" "*/';
  203. }
  204. if ( preg_match( '@";\\}\\s*\\}/\\*\\s+@', $m ) )
  205. {
  206. return '/*";}}/* */';
  207. }
  208. if ( preg_match( '@^/\\s*(\\S[\\s\\S]+?)\\s*/\\*@x', $m, $n ) )
  209. {
  210. return "/*/" . $n[1] . "/**/";
  211. }
  212. if ( substr( $m, -1 ) === '\\' )
  213. {
  214. return '/*\\*/';
  215. }
  216. if ( $m !== '' && $m[0] === '/' )
  217. {
  218. return '/*/*/';
  219. }
  220. return $hasSurroundingWs ? ' ' : '';
  221. }
  222. /**
  223. * CJzip::selectorsCB()
  224. *
  225. * @param mixed $m
  226. * @return
  227. */
  228. private function selectorsCB( $m )
  229. {
  230. return preg_replace( '/\\s*([,>+~])\\s*/', '$1', $m[0] );
  231. }
  232. /**
  233. * CJzip::fontFamilyCB()
  234. *
  235. * @param mixed $m
  236. * @return
  237. */
  238. private function fontFamilyCB( $m )
  239. {
  240. $m[1] = preg_replace( '/\\s*("[^"]+"|\'[^\']+\'|[\\w\\-]+)\\s*/x', '$1', $m[1] );
  241. return 'font-family:' . $m[1] . $m[2];
  242. }
  243. /**
  244. * CJzip::changeCssURL()
  245. *
  246. * @param mixed $matches
  247. * @return
  248. */
  249. private function changeCssURL( $matches )
  250. {
  251. $url = $this->cssImgNewPath . $matches[1];
  252. while ( preg_match( "/([^\/(\.\.)]+)\/\.\.\//", $url ) )
  253. {
  254. $url = preg_replace( "/([^\/(\.\.)]+)\/\.\.\//", "", $url );
  255. }
  256. return "url(" . $url . ")";
  257. }
  258. /**
  259. * CJzip::compress_css()
  260. *
  261. * @param mixed $cssContent
  262. * @return
  263. */
  264. private function compress_css( $cssContent )
  265. {
  266. $cssContent = preg_replace( "/url[\s]*\([\s]*[\'|\"](.*)?[\'|\"][\s]*\)/", "url($1)", $cssContent );
  267. $cssContent = preg_replace( '@>/\\*\\s*\\*/@', '>/*keep*/', $cssContent );
  268. $cssContent = preg_replace( '@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $cssContent );
  269. $cssContent = preg_replace( '@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $cssContent );
  270. $cssContent = preg_replace_callback( '@\\s*/\\*([\\s\\S]*?)\\*/\\s*@', array( $this, 'commentCB' ), $cssContent );
  271. $cssContent = preg_replace( '/[\s\t\r\n]+/', ' ', $cssContent );
  272. $cssContent = preg_replace( '/[\s]*(\:|\,|\;|\{|\})[\s]*/', "$1", $cssContent );
  273. $cssContent = preg_replace( "/[\#]+/", "#", $cssContent );
  274. $cssContent = str_replace( array( ' 0px', ':0px', ';}', ':0 0 0 0', ':0.', ' 0.' ), array( ' 0', ':0', '}', ':0', ':.', ' .' ), $cssContent );
  275. $cssContent = preg_replace( '/\\s*([{;])\\s*([\\*_]?[\\w\\-]+)\\s*:\\s*(\\b|[#\'"-])/x', '$1$2:$3', $cssContent );
  276. $cssContent = preg_replace_callback( '/(?:\\s*[^~>+,\\s]+\\s*[,>+~])+\\s*[^~>+,\\s]+{/x', array( $this, 'selectorsCB' ), $cssContent );
  277. $cssContent = preg_replace( '/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i', '$1#$2$3$4$5', $cssContent );
  278. $cssContent = preg_replace_callback( '/font-family:([^;}]+)([;}])/', array( $this, 'fontFamilyCB' ), $cssContent );
  279. $cssContent = preg_replace( '/@import\\s+url/', '@import url', $cssContent );
  280. $cssContent = preg_replace( '/:first-l(etter|ine)\\{/', ':first-l$1 {', $cssContent );
  281. $cssContent = preg_replace( "/[^\}]+\{[\s|\;]*\}[\s]*/", "", $cssContent );
  282. $cssContent = preg_replace( "/[\s]+/", " ", $cssContent );
  283. $cssContent = trim( $cssContent );
  284. return $cssContent;
  285. }
  286. /**
  287. * CJzip::compress_javascript()
  288. *
  289. * @param mixed $jsContent
  290. * @return
  291. */
  292. private function compress_javascript( $jsContent )
  293. {
  294. $jsContent = preg_replace( "/(\r\n)+|(\n|\r)+/", "\r\n", $jsContent );
  295. return $jsContent;
  296. }
  297. /**
  298. * CJzip::loadFile()
  299. *
  300. * @return
  301. */
  302. public function loadFile()
  303. {
  304. $hash = $this->file['lastmod'] . '-' . $this->file['md5file'];
  305. header( "Etag: \"" . $hash . "\"" );
  306. if ( $this->is_notModified( $hash ) ) $this->browseInfo( 304 );
  307. $this->encoding = $this->check_encode();
  308. $this->loadData();
  309. }
  310. }
  311. $CJzip = new CJzip;
  312. $CJzip->loadFile();
  313. ?>