PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/Opl/Opt/Output/Http.php

https://bitbucket.org/kandsten/hitta.sverok.se
PHP | 250 lines | 158 code | 18 blank | 74 comment | 33 complexity | c59e5b872f4916ee8e3ed51b079fbecd MD5 | raw file
Possible License(s): GPL-3.0, MIT
  1. <?php
  2. /*
  3. * OPEN POWER LIBS <http://www.invenzzia.org>
  4. *
  5. * This file is subject to the new BSD license that is bundled
  6. * with this package in the file LICENSE. It is also available through
  7. * WWW at this URL: <http://www.invenzzia.org/license/new-bsd>
  8. *
  9. * Copyright (c) Invenzzia Group <http://www.invenzzia.org>
  10. * and other contributors. See website for details.
  11. *
  12. * $Id: Http.php 241 2009-09-29 11:20:18Z zyxist $
  13. */
  14. class Opt_Output_Http implements Opt_Output_Interface
  15. {
  16. const XHTML = 0;
  17. const HTML = 1;
  18. const FORCED_XHTML = 2;
  19. const WML = 3;
  20. const XML = 4;
  21. const TXT = 5;
  22. protected $_tpl;
  23. protected $_mode;
  24. // Headers
  25. protected $_headers = array();
  26. protected $_headersSent = false;
  27. /**
  28. * The constructor that creates the new HTTP output object.
  29. */
  30. public function __construct()
  31. {
  32. $this->_tpl = Opl_Registry::get('opt');
  33. } // end __construct();
  34. /**
  35. * Returns the name of this output system.
  36. *
  37. * @return String The "HTTP" word.
  38. */
  39. public function getName()
  40. {
  41. return 'HTTP';
  42. } // end getName();
  43. /*
  44. * Header management
  45. */
  46. /**
  47. * Sets a HTTP header and secures it by removing the new line characters.
  48. *
  49. * @param String $name Header name
  50. * @param String $value Header value
  51. * @return Boolean True if succeed.
  52. */
  53. public function setHeader($name, $value)
  54. {
  55. if($this->_headersSent)
  56. {
  57. return false;
  58. }
  59. $name = strtr($name, "\r\n", ' ');
  60. $value = strtr($value, "\r\n", ' ');
  61. if(!$this->_tpl->headerBuffering)
  62. {
  63. header($name.': '.$value);
  64. }
  65. $this->_headers[$name] = $value;
  66. return true;
  67. } // end setHeader();
  68. /**
  69. * Returns the list of headers currently set in the output system.
  70. *
  71. * @return array
  72. */
  73. public function getHeaders()
  74. {
  75. return $this->_headers;
  76. } // end getHeaders();
  77. /**
  78. * Sends the buffered HTTP headers to the browser.
  79. *
  80. * @return Boolean True, if succeed.
  81. */
  82. public function sendHeaders()
  83. {
  84. if(!$this->_headersSent && $this->_tpl->headerBuffering)
  85. {
  86. foreach($this->headers as $name => $value)
  87. {
  88. if($name == 'HTTP/1.0' || $name == 'HTTP/1.1')
  89. {
  90. header($name.' '.$value);
  91. }
  92. else
  93. {
  94. header($name.': '.$value);
  95. }
  96. }
  97. return true;
  98. }
  99. return false;
  100. } // end sendHeaders();
  101. /**
  102. * Creates a "Content-type" header from the information provided in the
  103. * arguments or in OPT configuration. If one of the arguments is NULL,
  104. * the method tries to import equivalent setting from the Opt_Class configuration
  105. * fields.
  106. *
  107. * If Open Power Classes is available, the method may perform a full
  108. * content-negotiation procedure.
  109. *
  110. * @param String|Int $contentType The content type described manually or by the class constants.
  111. * @param String $charset The output document encoding.
  112. */
  113. public function setContentType($contentType = null, $charset = null)
  114. {
  115. $charset = (is_null($charset) ? $this->_tpl->charset : $charset);
  116. $contentType = (is_null($contentType) ? $this->_tpl->contentType : $contentType);
  117. $this->_tpl->charset = $charset;
  118. $this->_tpl->contentType = $contentType;
  119. if(!is_null($charset))
  120. {
  121. $charset = ';charset='.$charset;
  122. }
  123. $replacements = array(
  124. self::HTML => 'text/html',
  125. self::XML => 'application/xml',
  126. self::WML => 'text/vnd.wap.wml',
  127. self::TXT => 'text/plain'
  128. );
  129. if($this->_tpl->contentNegotiation)
  130. {
  131. // This part of the code requires OPC!
  132. $visit = Opc_Visit::getInstance();
  133. if($contentType == self::XHTML)
  134. {
  135. // Choose XHTML or HTML depending on their priority
  136. $contentType = 'text/html';
  137. foreach($visit->mimeTypes as $type)
  138. {
  139. if($type == 'application/xhtml+xml' || $type == 'text/html')
  140. {
  141. $contentType = $type;
  142. break;
  143. }
  144. }
  145. }
  146. elseif($contentType == self::FORCED_XHTML)
  147. {
  148. // Choose XHTML, if the browser accepts it.
  149. $contentType = 'text/html';
  150. if(in_array('application/xhtml+xml',$visit->mimeTypes))
  151. {
  152. $contentType = 'application/xhtml+xml';
  153. }
  154. }
  155. else
  156. {
  157. // Optionally convert the other constants and check whether
  158. // the browser supports them.
  159. if(in_array($contentType, $replacements))
  160. {
  161. $contentType = $replacements[$replacements];
  162. }
  163. if(!in_array($contentType, $visit->mimeTypes))
  164. {
  165. $contentType = 'application/octet-stream';
  166. }
  167. }
  168. $this->setHeader('Vary', 'Accept');
  169. }
  170. else
  171. {
  172. // No content-negotiation. Do the basic checks only.
  173. if($contentType == self::XHTML || $contentType == self::FORCED_XHTML)
  174. {
  175. if($this->_tpl->debugConsole)
  176. {
  177. $contentType = 'text/html';
  178. }
  179. elseif(stristr($_SERVER['HTTP_ACCEPT'], 'application/xhtml+xml'))
  180. {
  181. $contentType = 'application/xhtml+xml';
  182. }
  183. else
  184. {
  185. $contentType = 'text/html';
  186. }
  187. }
  188. elseif(isset($replacements[$contentType]))
  189. {
  190. $contentType = $replacements[$contentType];
  191. }
  192. }
  193. $this->setHeader('Content-type', $contentType.$charset);
  194. } // end setContentType();
  195. /*
  196. * Template rendering
  197. */
  198. /**
  199. * Renders the view and sends the results to the browser. Please note
  200. * that in order to ensure that the script output will be a valid
  201. * XML document, this method can be called only once, for one XML view, forcing
  202. * you to modularize the templates with the template inheritance or
  203. * opt:include instruction.
  204. *
  205. * @param Opt_View $view The view object to be rendered.
  206. * @return Boolean True, if succeed.
  207. */
  208. public function render(Opt_View $view)
  209. {
  210. if(is_null($this->_mode))
  211. {
  212. $this->_mode = $view->getMode();
  213. // Initialize output buffering and turn on the compression, if necessary.
  214. if(!$this->_tpl->debugConsole && $this->_tpl->gzipCompression == true && extension_loaded('zlib') && ini_get('zlib.output_compression') == 0)
  215. {
  216. ob_start('ob_gzhandler');
  217. ob_implicit_flush(0);
  218. }
  219. else
  220. {
  221. ob_start();
  222. }
  223. // Send the headers, if necessary
  224. $this->sendHeaders();
  225. }
  226. elseif($this->_mode == Opt_Class::XML_MODE)
  227. {
  228. throw new Opt_OutputOverloaded_Exception;
  229. }
  230. return $view->_parse($this, true);
  231. } // end output();
  232. } // end Opt_Output_Http;