PageRenderTime 69ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/libraries/joomla/environment/response.php

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