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

/libraries/joomla/environment/response.php

https://bitbucket.org/joomla/joomla-platform/
PHP | 306 lines | 126 code | 39 blank | 141 comment | 21 complexity | 428970df35d0240aa9ab39c92f03fc76 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Environment
  5. *
  6. * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. /**
  11. * JResponse Class.
  12. *
  13. * This class serves to provide the Joomla Framework with a common interface to access
  14. * response variables. This includes header and body.
  15. *
  16. * @package Joomla.Platform
  17. * @subpackage Environment
  18. * @since 11.1
  19. */
  20. class JResponse
  21. {
  22. /**
  23. * @var array
  24. * @since 11.1
  25. */
  26. protected static $body = array();
  27. /**
  28. * @var boolean
  29. * @since 11.1
  30. */
  31. protected static $cachable = false;
  32. /**
  33. * @var array
  34. * @since 11.1
  35. */
  36. protected static $headers = array();
  37. /**
  38. * Set/get cachable state for the response.
  39. *
  40. * If $allow is set, sets the cachable state of the response. Always returns current state.
  41. *
  42. * @param boolean $allow
  43. *
  44. * @return boolean True of browser caching should be allowed
  45. * @since 11.1
  46. */
  47. public static function allowCache($allow = null)
  48. {
  49. if (!is_null($allow)) {
  50. self::$cachable = (bool) $allow;
  51. }
  52. return self::$cachable;
  53. }
  54. /**
  55. * Set a header.
  56. *
  57. * If $replace is true, replaces any headers already defined with that $name.
  58. *
  59. * @param string $name
  60. * @param string $value
  61. * @param boolean $replace
  62. *
  63. * @return void
  64. * @since 11.1
  65. */
  66. public static function setHeader($name, $value, $replace = false)
  67. {
  68. $name = (string) $name;
  69. $value = (string) $value;
  70. if ($replace) {
  71. foreach (self::$headers as $key => $header)
  72. {
  73. if ($name == $header['name']) {
  74. unset(self::$headers[$key]);
  75. }
  76. }
  77. }
  78. self::$headers[] = array(
  79. 'name' => $name,
  80. 'value' => $value
  81. );
  82. }
  83. /**
  84. * Return array of headers.
  85. *
  86. * @return array
  87. * @since 11.1
  88. */
  89. public static function getHeaders()
  90. {
  91. return self::$headers;
  92. }
  93. /**
  94. * Clear headers.
  95. *
  96. * @return void
  97. * @since 11.1
  98. */
  99. public static function clearHeaders()
  100. {
  101. self::$headers = array();
  102. }
  103. /**
  104. * Send all headers.
  105. *
  106. * @return void
  107. * @since 11.1
  108. */
  109. public static function sendHeaders()
  110. {
  111. if (!headers_sent()) {
  112. foreach (self::$headers as $header)
  113. {
  114. if ('status' == strtolower($header['name'])) {
  115. // 'status' headers indicate an HTTP status, and need to be handled slightly differently
  116. header(ucfirst(strtolower($header['name'])) . ': ' . $header['value'], null, (int) $header['value']);
  117. }
  118. else {
  119. header($header['name'] . ': ' . $header['value']);
  120. }
  121. }
  122. }
  123. }
  124. /**
  125. * Set body content.
  126. *
  127. * If body content already defined, this will replace it.
  128. *
  129. * @param string $content
  130. *
  131. * @return void
  132. * @since 11.1
  133. */
  134. public static function setBody($content)
  135. {
  136. self::$body = array((string) $content);
  137. }
  138. /**
  139. * Prepend content to the body content
  140. *
  141. * @param string $content
  142. *
  143. * @return void
  144. * @since 11.1
  145. */
  146. public static function prependBody($content)
  147. {
  148. array_unshift(self::$body, (string) $content);
  149. }
  150. /**
  151. * Append content to the body content
  152. *
  153. * @param string $content
  154. *
  155. * @return void
  156. * @since 11.1
  157. */
  158. public static function appendBody($content)
  159. {
  160. array_push(self::$body, (string) $content);
  161. }
  162. /**
  163. * Return the body content
  164. *
  165. * @param boolean $toArray Whether or not to return the body content as an array of strings or as a single string; defaults to false.
  166. *
  167. * @return string|array
  168. * @since 11.1
  169. */
  170. public static function getBody($toArray = false)
  171. {
  172. if ($toArray) {
  173. return self::$body;
  174. }
  175. ob_start();
  176. foreach (self::$body as $content)
  177. {
  178. echo $content;
  179. }
  180. return ob_get_clean();
  181. }
  182. /**
  183. * Sends all headers prior to returning the string
  184. *
  185. * @param boolean $compress If true, compress the data
  186. *
  187. * @return string
  188. * @since 11.1
  189. */
  190. public static function toString($compress = false)
  191. {
  192. $data = self::getBody();
  193. // Don't compress something if the server is going to do it anyway. Waste of time.
  194. if ($compress && !ini_get('zlib.output_compression') && ini_get('output_handler')!='ob_gzhandler') {
  195. $data = self::compress($data);
  196. }
  197. if (self::allowCache() === false) {
  198. self::setHeader('Cache-Control', 'no-cache', false);
  199. // HTTP 1.0
  200. self::setHeader('Pragma', 'no-cache');
  201. }
  202. self::sendHeaders();
  203. return $data;
  204. }
  205. /**
  206. * Compress the data
  207. *
  208. * Checks the accept encoding of the browser and compresses the data before
  209. * sending it to the client.
  210. *
  211. * @param string $data data
  212. *
  213. * @return string compressed data
  214. * @since 11.1 Replaces _compress method in 11.1
  215. */
  216. protected static function compress($data)
  217. {
  218. $encoding = self::clientEncoding();
  219. if (!$encoding) {
  220. return $data;
  221. }
  222. if (!extension_loaded('zlib') || ini_get('zlib.output_compression')) {
  223. return $data;
  224. }
  225. if (headers_sent()) {
  226. return $data;
  227. }
  228. if (connection_status() !== 0) {
  229. return $data;
  230. }
  231. $level = 4; // ideal level
  232. /*
  233. $size = strlen($data);
  234. $crc = crc32($data);
  235. $gzdata = "\x1f\x8b\x08\x00\x00\x00\x00\x00";
  236. $gzdata .= gzcompress($data, $level);
  237. $gzdata = substr($gzdata, 0, strlen($gzdata) - 4);
  238. $gzdata .= pack("V",$crc) . pack("V", $size);
  239. */
  240. $gzdata = gzencode($data, $level);
  241. self::setHeader('Content-Encoding', $encoding);
  242. self::setHeader('X-Content-Encoded-By', 'Joomla! 1.6');
  243. return $gzdata;
  244. }
  245. /**
  246. * Check, whether client supports compressed data
  247. *
  248. * @return boolean
  249. * @since 11.1 Replaces _clientEncoding method from 11.1
  250. */
  251. protected static function clientEncoding()
  252. {
  253. if (!isset($_SERVER['HTTP_ACCEPT_ENCODING'])) {
  254. return false;
  255. }
  256. $encoding = false;
  257. if (false !== strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) {
  258. $encoding = 'gzip';
  259. }
  260. if (false !== strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip')) {
  261. $encoding = 'x-gzip';
  262. }
  263. return $encoding;
  264. }
  265. }