/plugins/system/t3/includes/minify/closurecompiler.php

https://gitlab.com/lankerd/paGO---Testing-Site · PHP · 141 lines · 98 code · 9 blank · 34 comment · 11 complexity · e7838fbaa7ba249f19af18f0a1efeaca MD5 · raw file

  1. <?php
  2. /**
  3. * Class Minify_JS_ClosureCompiler
  4. * @package Minify
  5. */
  6. /**
  7. * Minify Javascript using Google's Closure Compiler API
  8. *
  9. * @link http://code.google.com/closure/compiler/
  10. * @package Minify
  11. * @author Stephen Clay <steve@mrclay.org>
  12. *
  13. * @todo can use a stream wrapper to unit test this?
  14. */
  15. class Minify_JS_ClosureCompiler {
  16. const URL = 'http://closure-compiler.appspot.com/compile';
  17. /**
  18. * Minify Javascript code via HTTP request to the Closure Compiler API
  19. *
  20. * @param string $js input code
  21. * @param array $options unused at this point
  22. * @return string
  23. */
  24. public static function minify($js, array $options = array())
  25. {
  26. $obj = new self($options);
  27. return $obj->min($js);
  28. }
  29. /**
  30. *
  31. * @param array $options
  32. *
  33. * fallbackFunc : default array($this, 'fallback');
  34. */
  35. public function __construct(array $options = array())
  36. {
  37. $this->_fallbackFunc = isset($options['fallbackMinifier'])
  38. ? $options['fallbackMinifier']
  39. : array($this, '_fallback');
  40. }
  41. public function min($js)
  42. {
  43. $postBody = $this->_buildPostBody($js);
  44. $bytes = (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2))
  45. ? mb_strlen($postBody, '8bit')
  46. : strlen($postBody);
  47. if ($bytes > 200000) {
  48. //T3 Framework
  49. //instead of throwing error, we use fall back option
  50. if (is_callable($this->_fallbackFunc)) {
  51. $response = "/*\n(Using fallback minifier)\n*/\n";
  52. $response .= call_user_func($this->_fallbackFunc, $js);
  53. } else {
  54. throw new Minify_JS_ClosureCompiler_Exception(
  55. 'POST content larger than 200000 bytes'
  56. );
  57. }
  58. }
  59. $response = $this->_getResponse($postBody);
  60. if (preg_match('/^Error\(\d\d?\):/', $response)) {
  61. if (is_callable($this->_fallbackFunc)) {
  62. $response = "/* Received errors from Closure Compiler API:\n$response"
  63. . "\n(Using fallback minifier)\n*/\n";
  64. $response .= call_user_func($this->_fallbackFunc, $js);
  65. } else {
  66. throw new Minify_JS_ClosureCompiler_Exception($response);
  67. }
  68. }
  69. if ($response === '') {
  70. $errors = $this->_getResponse($this->_buildPostBody($js, true));
  71. throw new Minify_JS_ClosureCompiler_Exception($errors);
  72. }
  73. return $response;
  74. }
  75. protected $_fallbackFunc = null;
  76. protected function _getResponse($postBody)
  77. {
  78. $allowUrlFopen = preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen'));
  79. if ($allowUrlFopen) {
  80. $contents = file_get_contents(self::URL, false, stream_context_create(array(
  81. 'http' => array(
  82. 'method' => 'POST',
  83. 'header' => "Content-type: application/x-www-form-urlencoded\r\nConnection: close\r\n",
  84. 'content' => $postBody,
  85. 'max_redirects' => 0,
  86. 'timeout' => 15,
  87. )
  88. )));
  89. } elseif (defined('CURLOPT_POST')) {
  90. $ch = curl_init(self::URL);
  91. curl_setopt($ch, CURLOPT_POST, true);
  92. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  93. curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded'));
  94. curl_setopt($ch, CURLOPT_POSTFIELDS, $postBody);
  95. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
  96. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
  97. $contents = curl_exec($ch);
  98. curl_close($ch);
  99. } else {
  100. throw new Minify_JS_ClosureCompiler_Exception(
  101. "Could not make HTTP request: allow_url_open is false and cURL not available"
  102. );
  103. }
  104. if (false === $contents) {
  105. throw new Minify_JS_ClosureCompiler_Exception(
  106. "No HTTP response from server"
  107. );
  108. }
  109. return trim($contents);
  110. }
  111. protected function _buildPostBody($js, $returnErrors = false)
  112. {
  113. return http_build_query(array(
  114. 'js_code' => $js,
  115. 'output_info' => ($returnErrors ? 'errors' : 'compiled_code'),
  116. 'output_format' => 'text',
  117. 'compilation_level' => 'SIMPLE_OPTIMIZATIONS'
  118. ), null, '&');
  119. }
  120. /**
  121. * Default fallback function if CC API fails
  122. * @param string $js
  123. * @return string
  124. */
  125. protected function _fallback($js)
  126. {
  127. //T3 Framework
  128. T3::import('minify/jsmin');
  129. return JSMin::minify($js);
  130. }
  131. }
  132. class Minify_JS_ClosureCompiler_Exception extends Exception {}