PageRenderTime 72ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/t/upfront/library/class_upfront_compression.php

https://bitbucket.org/matthewselby/wpdev
PHP | 157 lines | 72 code | 19 blank | 66 comment | 21 complexity | 2a9f2671914107bc2f8095b5fb2c5c1c MD5 | raw file
Possible License(s): Apache-2.0, GPL-2.0, LGPL-3.0, LGPL-2.1, AGPL-1.0, BSD-3-Clause, MIT, GPL-3.0, MPL-2.0-no-copyleft-exception
  1. <?php
  2. /**
  3. * Handle data compression and extraction, uses Gzip
  4. *
  5. * @author Jeffri Tjin
  6. */
  7. class Upfront_Compression {
  8. /* Method of compression, currently supported: zlib */
  9. static protected $method = "zlib";
  10. /* Level of compression, usually ranged from 1-9 */
  11. static protected $level = 1;
  12. static public function init () {
  13. if ( defined("UPFRONT_SAVE_COMPRESSION_METHOD") ) self::$method = UPFRONT_SAVE_COMPRESSION_METHOD;
  14. if ( defined("UPFRONT_SAVE_COMPRESSION_LEVEL") ) self::$level = UPFRONT_SAVE_COMPRESSION_LEVEL;
  15. }
  16. /**
  17. * Check if compression is enabled, can be disabled by constant or option
  18. * Will be automatically disabled if extension isn't supported
  19. *
  20. * @return bool
  21. */
  22. static public function is_enabled () {
  23. if ( defined("UPFRONT_DISABLE_SAVE_COMPRESSION") && UPFRONT_DISABLE_SAVE_COMPRESSION ) return false;
  24. $disable_compression = Upfront_Cache_Utils::get_option('upfront_disable_save_compression');
  25. if ( !empty($disable_compression) ) return false;
  26. if ( "zlib" === self::$method ) return extension_loaded('zlib');
  27. return false;
  28. }
  29. /**
  30. * Return the compression level
  31. *
  32. * @return int Compression level
  33. */
  34. static public function get_level () {
  35. return self::$level;
  36. }
  37. /**
  38. * Extract base64 encoded string of compressed data to the original data
  39. *
  40. * @param string $encoded_string base64 encoded string of compressed data
  41. * @param int $compressed_length verify compressed length before processing, pass 0 for no verification
  42. * @param int $original_length verify original length after processing, pass 0 for no verification
  43. * @param bool $assoc return associative array or not
  44. *
  45. * @return mixed original data
  46. */
  47. static public function extract ($encoded_string, $compressed_length = 0, $original_length = 0, $assoc = true) {
  48. if ( !self::is_enabled() ) return false;
  49. if ( "zlib" === self::$method ) {
  50. return self::_gz_extract($encoded_string, $compressed_length, $original_length, $assoc);
  51. }
  52. return false;
  53. }
  54. /**
  55. * Uses gzinflate for extract
  56. *
  57. * @param string $encoded_string base64 encoded string of compressed data
  58. * @param int $compressed_length verify compressed length before processing, pass 0 for no verification
  59. * @param int $original_length verify original length after processing, pass 0 for no verification
  60. *
  61. * @return mixed original data
  62. */
  63. static protected function _gz_extract ($encoded_string, $compressed_length = 0, $original_length = 0, $assoc = true) {
  64. if ( $compressed_length > 0 && $compressed_length !== self::_strlen($encoded_string) ) return false;
  65. $extracted = gzinflate( base64_decode($encoded_string) );
  66. if ( $original_length > 0 && $original_length !== self::_strlen($extracted) ) return false;
  67. return json_decode($extracted, $assoc);
  68. }
  69. /**
  70. * Compress data and return base64 encoded string
  71. *
  72. * @param mixed $data
  73. * @param int $level
  74. *
  75. * @return array array consisting of compressed base64 encoded string, original length and compressed length
  76. */
  77. static public function compress ($data, $level = false) {
  78. if ( !self::is_enabled() ) return false;
  79. if ( !is_numeric($level) || $level < 1 ) $level = self::$level;
  80. if ( "zlib" === self::$method ) {
  81. return self::_gz_compress($data, $level);
  82. }
  83. return false;
  84. }
  85. /**
  86. * Uses gzdeflate for compression
  87. *
  88. * @param mixed $data
  89. * @param int $level
  90. *
  91. * @return array array consisting of compressed base64 encoded string, original length and compressed length
  92. */
  93. static protected function _gz_compress ($data, $level) {
  94. $json_string = json_encode($data);
  95. $compressed = gzdeflate($json_string, $level);
  96. $encoded = base64_encode($compressed);
  97. return array(
  98. 'result' => $encoded,
  99. 'original_length' => strlen($json_string),
  100. 'compressed_length' => strlen($encoded)
  101. );
  102. }
  103. /**
  104. * Automatically extract data from $_POST['data'] or from passed param
  105. *
  106. * @param array $data
  107. * @param string $fields
  108. * @param bool $assoc
  109. * @return mixed extracted data
  110. */
  111. static public function extract_from_request ($data = null, $fields = null, $assoc = true) {
  112. if ( !self::is_enabled() ) return false;
  113. $data = null === $data ? $_POST : $data;
  114. $use_compression = ( !empty($data['compression']) && 1 === intval($data['compression']) );
  115. if ( !$use_compression ) return false;
  116. if ( null === $fields ) {
  117. $fields = array(
  118. 'data' => "data",
  119. 'original_length' => "original_length",
  120. 'compressed_length' => "compressed_length"
  121. );
  122. }
  123. $original_length = !empty($data[$fields['original_length']]) ? intval($data[$fields['original_length']]) : 0;
  124. $compressed_length = !empty($data[$fields['compressed_length']]) ? intval($data[$fields['compressed_length']]) : 0;
  125. $extracted = !empty($data[$fields['data']]) ? self::extract($data[$fields['data']], $compressed_length, $original_length, $assoc) : false;
  126. return $extracted;
  127. }
  128. /**
  129. * Safe method of getting string length properly
  130. *
  131. * @param $string
  132. */
  133. static protected function _strlen ($string) {
  134. if ( function_exists("mb_strlen") ) return mb_strlen($string);
  135. return strlen( utf8_decode($string) );
  136. }
  137. }
  138. Upfront_Compression::init();