BxDolGzip.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup UnaCore UNA Core
  7. * @{
  8. */
  9. class BxDolGzip extends BxDol
  10. {
  11. protected $_sType;
  12. protected $_bGzip;
  13. protected $_sEncoding;
  14. protected $_iExpirationOffset;
  15. protected $_sInFile;
  16. protected $_sOutFile;
  17. protected $_sOutContent;
  18. protected $_sOutContentZipped;
  19. function __construct($sFile)
  20. {
  21. parent::__construct();
  22. $this->_iExpirationOffset = 3600 * 24 * 30;
  23. $this->_sInFile = BX_DIRECTORY_PATH_CACHE_PUBLIC . $sFile;
  24. $this->_sOutFile = BX_DIRECTORY_PATH_CACHE_PUBLIC . $sFile . '.gz';
  25. $aMatches = array();
  26. if(!preg_match("/^([a-z0-9_-]+)\.(js|css|js\.map)$/", $sFile, $aMatches))
  27. die('BxDolGzip: file is not js/css/js.map');
  28. switch($aMatches[2]) {
  29. case 'css':
  30. $this->_sType = 'text/css';
  31. break;
  32. case 'js':
  33. $this->_sType = 'text/javascript';
  34. break;
  35. case 'js.map': // source map of a compiled JS bundle
  36. $this->_sType = 'application/json';
  37. break;
  38. }
  39. $this->_sOutContent = "";
  40. $this->_sOutContentZipped = "";
  41. }
  42. static function load($sFile)
  43. {
  44. $oLoader = new BxDolGzip($sFile);
  45. $oLoader->prepare();
  46. $oLoader->read();
  47. $oLoader->output();
  48. }
  49. function prepare()
  50. {
  51. header("Content-type: " . $this->_sType);
  52. header("Vary: Accept-Encoding");
  53. header("Cache-control: max-age=" . $this->_iExpirationOffset . ", public");
  54. $encodings = array ();
  55. if (isset($_SERVER['HTTP_ACCEPT_ENCODING']))
  56. $encodings = explode(',', strtolower(preg_replace("/\s+/", "", $_SERVER['HTTP_ACCEPT_ENCODING'])));
  57. if ((in_array('gzip', $encodings) || in_array('x-gzip', $encodings) || isset($_SERVER['---------------'])) && function_exists('ob_gzhandler') && !ini_get('zlib.output_compression')) {
  58. $this->_sEncoding = in_array('x-gzip', $encodings) ? "x-gzip" : "gzip";
  59. $this->_bGzip = true;
  60. }
  61. }
  62. function read()
  63. {
  64. if($this->_bGzip && file_exists($this->_sOutFile))
  65. $this->_sOutContentZipped = $this->getFileContents($this->_sOutFile);
  66. else
  67. $this->_sOutContent = $this->getFileContents($this->_sInFile);
  68. }
  69. function output()
  70. {
  71. if(!$this->_bGzip) {
  72. echo $this->_sOutContent;
  73. return;
  74. }
  75. header("Content-Encoding: " . $this->_sEncoding);
  76. if(!empty($this->_sOutContentZipped)) {
  77. echo $this->_sOutContentZipped;
  78. return;
  79. }
  80. if (!$this->_sOutContent)
  81. return;
  82. $this->_sOutContentZipped = gzencode($this->_sOutContent, 9, FORCE_GZIP);
  83. $this->putFileContents($this->_sOutFile, $this->_sOutContentZipped);
  84. echo $this->_sOutContentZipped;
  85. }
  86. function getFileContents($sPath)
  87. {
  88. $sPath = realpath($sPath);
  89. if(!$sPath || !@is_file($sPath))
  90. return "";
  91. if(function_exists("file_get_contents"))
  92. return @file_get_contents($sPath);
  93. $sContent = "";
  94. if(!($rHandler = @fopen($sPath, "r")))
  95. return "";
  96. while(!feof($rHandler))
  97. $sContent .= fgets($rHandler);
  98. fclose($rHandler);
  99. return $sContent;
  100. }
  101. function putFileContents($sPath, $sContent)
  102. {
  103. if (function_exists("file_put_contents"))
  104. return @file_put_contents($sPath, $sContent);
  105. if(!($rHandler = @fopen($sPath, "wb")))
  106. return 0;
  107. $iResult = (int)fwrite($rHandler, $sContent);
  108. fclose($rHandler);
  109. return $iResult;
  110. }
  111. }
  112. /** @} */