/system/libraries/Output.php

https://bitbucket.org/ksokmesa/sina-asian · PHP · 409 lines · 185 code · 68 blank · 156 comment · 27 complexity · 0a60aaea23e789b43849c7250068e259 MD5 · raw file

  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP 4.3.2 or newer
  6. *
  7. * @package CodeIgniter
  8. * @author ExpressionEngine Dev Team
  9. * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc.
  10. * @license http://codeigniter.com/user_guide/license.html
  11. * @link http://codeigniter.com
  12. * @since Version 1.0
  13. * @filesource
  14. */
  15. // ------------------------------------------------------------------------
  16. /**
  17. * Output Class
  18. *
  19. * Responsible for sending final output to browser
  20. *
  21. * @package CodeIgniter
  22. * @subpackage Libraries
  23. * @category Output
  24. * @author ExpressionEngine Dev Team
  25. * @link http://codeigniter.com/user_guide/libraries/output.html
  26. */
  27. class CI_Output {
  28. var $final_output;
  29. var $cache_expiration = 0;
  30. var $headers = array();
  31. var $enable_profiler = FALSE;
  32. function CI_Output()
  33. {
  34. log_message('debug', "Output Class Initialized");
  35. }
  36. // --------------------------------------------------------------------
  37. /**
  38. * Get Output
  39. *
  40. * Returns the current output string
  41. *
  42. * @access public
  43. * @return string
  44. */
  45. function get_output()
  46. {
  47. return $this->final_output;
  48. }
  49. // --------------------------------------------------------------------
  50. /**
  51. * Set Output
  52. *
  53. * Sets the output string
  54. *
  55. * @access public
  56. * @param string
  57. * @return void
  58. */
  59. function set_output($output)
  60. {
  61. $this->final_output = $output;
  62. }
  63. // --------------------------------------------------------------------
  64. /**
  65. * Append Output
  66. *
  67. * Appends data onto the output string
  68. *
  69. * @access public
  70. * @param string
  71. * @return void
  72. */
  73. function append_output($output)
  74. {
  75. if ($this->final_output == '')
  76. {
  77. $this->final_output = $output;
  78. }
  79. else
  80. {
  81. $this->final_output .= $output;
  82. }
  83. }
  84. // --------------------------------------------------------------------
  85. /**
  86. * Set Header
  87. *
  88. * Lets you set a server header which will be outputted with the final display.
  89. *
  90. * Note: If a file is cached, headers will not be sent. We need to figure out
  91. * how to permit header data to be saved with the cache data...
  92. *
  93. * @access public
  94. * @param string
  95. * @return void
  96. */
  97. function set_header($header, $replace = TRUE)
  98. {
  99. $this->headers[] = array($header, $replace);
  100. }
  101. // --------------------------------------------------------------------
  102. /**
  103. * Set HTTP Status Header
  104. * moved to Common procedural functions in 1.7.2
  105. *
  106. * @access public
  107. * @param int the status code
  108. * @param string
  109. * @return void
  110. */
  111. function set_status_header($code = '200', $text = '')
  112. {
  113. set_status_header($code, $text);
  114. }
  115. // --------------------------------------------------------------------
  116. /**
  117. * Enable/disable Profiler
  118. *
  119. * @access public
  120. * @param bool
  121. * @return void
  122. */
  123. function enable_profiler($val = TRUE)
  124. {
  125. $this->enable_profiler = (is_bool($val)) ? $val : TRUE;
  126. }
  127. // --------------------------------------------------------------------
  128. /**
  129. * Set Cache
  130. *
  131. * @access public
  132. * @param integer
  133. * @return void
  134. */
  135. function cache($time)
  136. {
  137. $this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;
  138. }
  139. // --------------------------------------------------------------------
  140. /**
  141. * Display Output
  142. *
  143. * All "view" data is automatically put into this variable by the controller class:
  144. *
  145. * $this->final_output
  146. *
  147. * This function sends the finalized output data to the browser along
  148. * with any server headers and profile data. It also stops the
  149. * benchmark timer so the page rendering speed and memory usage can be shown.
  150. *
  151. * @access public
  152. * @return mixed
  153. */
  154. function _display($output = '')
  155. {
  156. // Note: We use globals because we can't use $CI =& get_instance()
  157. // since this function is sometimes called by the caching mechanism,
  158. // which happens before the CI super object is available.
  159. global $BM, $CFG;
  160. // --------------------------------------------------------------------
  161. // Set the output data
  162. if ($output == '')
  163. {
  164. $output =& $this->final_output;
  165. }
  166. // --------------------------------------------------------------------
  167. // Do we need to write a cache file?
  168. if ($this->cache_expiration > 0)
  169. {
  170. $this->_write_cache($output);
  171. }
  172. // --------------------------------------------------------------------
  173. // Parse out the elapsed time and memory usage,
  174. // then swap the pseudo-variables with the data
  175. $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');
  176. $output = str_replace('{elapsed_time}', $elapsed, $output);
  177. $memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
  178. $output = str_replace('{memory_usage}', $memory, $output);
  179. // --------------------------------------------------------------------
  180. // Is compression requested?
  181. if ($CFG->item('compress_output') === TRUE)
  182. {
  183. if (extension_loaded('zlib'))
  184. {
  185. if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
  186. {
  187. ob_start('ob_gzhandler');
  188. }
  189. }
  190. }
  191. // --------------------------------------------------------------------
  192. // Are there any server headers to send?
  193. if (count($this->headers) > 0)
  194. {
  195. foreach ($this->headers as $header)
  196. {
  197. @header($header[0], $header[1]);
  198. }
  199. }
  200. // --------------------------------------------------------------------
  201. // Does the get_instance() function exist?
  202. // If not we know we are dealing with a cache file so we'll
  203. // simply echo out the data and exit.
  204. if ( ! function_exists('get_instance'))
  205. {
  206. echo $output;
  207. log_message('debug', "Final output sent to browser");
  208. log_message('debug', "Total execution time: ".$elapsed);
  209. return TRUE;
  210. }
  211. // --------------------------------------------------------------------
  212. // Grab the super object. We'll need it in a moment...
  213. $CI =& get_instance();
  214. // Do we need to generate profile data?
  215. // If so, load the Profile class and run it.
  216. if ($this->enable_profiler == TRUE)
  217. {
  218. $CI->load->library('profiler');
  219. // If the output data contains closing </body> and </html> tags
  220. // we will remove them and add them back after we insert the profile data
  221. if (preg_match("|</body>.*?</html>|is", $output))
  222. {
  223. $output = preg_replace("|</body>.*?</html>|is", '', $output);
  224. $output .= $CI->profiler->run();
  225. $output .= '</body></html>';
  226. }
  227. else
  228. {
  229. $output .= $CI->profiler->run();
  230. }
  231. }
  232. // --------------------------------------------------------------------
  233. // Does the controller contain a function named _output()?
  234. // If so send the output there. Otherwise, echo it.
  235. if (method_exists($CI, '_output'))
  236. {
  237. $CI->_output($output);
  238. }
  239. else
  240. {
  241. echo $output; // Send it to the browser!
  242. }
  243. log_message('debug', "Final output sent to browser");
  244. log_message('debug', "Total execution time: ".$elapsed);
  245. }
  246. // --------------------------------------------------------------------
  247. /**
  248. * Write a Cache File
  249. *
  250. * @access public
  251. * @return void
  252. */
  253. function _write_cache($output)
  254. {
  255. $CI =& get_instance();
  256. $path = $CI->config->item('cache_path');
  257. $cache_path = ($path == '') ? BASEPATH.'cache/' : $path;
  258. if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
  259. {
  260. return;
  261. }
  262. $uri = $CI->config->item('base_url').
  263. $CI->config->item('index_page').
  264. $CI->uri->uri_string();
  265. $cache_path .= md5($uri);
  266. if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE))
  267. {
  268. log_message('error', "Unable to write cache file: ".$cache_path);
  269. return;
  270. }
  271. $expire = time() + ($this->cache_expiration * 60);
  272. if (flock($fp, LOCK_EX))
  273. {
  274. fwrite($fp, $expire.'TS--->'.$output);
  275. flock($fp, LOCK_UN);
  276. }
  277. else
  278. {
  279. log_message('error', "Unable to secure a file lock for file at: ".$cache_path);
  280. return;
  281. }
  282. fclose($fp);
  283. @chmod($cache_path, DIR_WRITE_MODE);
  284. log_message('debug', "Cache file written: ".$cache_path);
  285. }
  286. // --------------------------------------------------------------------
  287. /**
  288. * Update/serve a cached file
  289. *
  290. * @access public
  291. * @return void
  292. */
  293. function _display_cache(&$CFG, &$URI)
  294. {
  295. $cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path');
  296. if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
  297. {
  298. return FALSE;
  299. }
  300. // Build the file path. The file name is an MD5 hash of the full URI
  301. $uri = $CFG->item('base_url').
  302. $CFG->item('index_page').
  303. $URI->uri_string;
  304. $filepath = $cache_path.md5($uri);
  305. if ( ! @file_exists($filepath))
  306. {
  307. return FALSE;
  308. }
  309. if ( ! $fp = @fopen($filepath, FOPEN_READ))
  310. {
  311. return FALSE;
  312. }
  313. flock($fp, LOCK_SH);
  314. $cache = '';
  315. if (filesize($filepath) > 0)
  316. {
  317. $cache = fread($fp, filesize($filepath));
  318. }
  319. flock($fp, LOCK_UN);
  320. fclose($fp);
  321. // Strip out the embedded timestamp
  322. if ( ! preg_match("/(\d+TS--->)/", $cache, $match))
  323. {
  324. return FALSE;
  325. }
  326. // Has the file expired? If so we'll delete it.
  327. if (time() >= trim(str_replace('TS--->', '', $match['1'])))
  328. {
  329. @unlink($filepath);
  330. log_message('debug', "Cache file has expired. File deleted");
  331. return FALSE;
  332. }
  333. // Display the cache
  334. $this->_display(str_replace($match['0'], '', $cache));
  335. log_message('debug', "Cache file is current. Sending it to browser.");
  336. return TRUE;
  337. }
  338. }
  339. // END Output Class
  340. /* End of file Output.php */
  341. /* Location: ./system/libraries/Output.php */