blob: 0683539c91015e487db8c7b04efbb9d300cb4603 [file] [log] [blame]
Andrey Andreev1f5fbb62012-01-07 20:53:29 +02001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreev1f5fbb62012-01-07 20:53:29 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev1f5fbb62012-01-07 20:53:29 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
Greg Aker0defe5d2012-01-01 18:46:41 -060021 * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
27
Derek Allard2067d1a2008-11-13 22:59:24 +000028/**
29 * Output Class
30 *
31 * Responsible for sending final output to browser
32 *
33 * @package CodeIgniter
34 * @subpackage Libraries
35 * @category Output
Derek Jonesf4a4bd82011-10-20 12:18:42 -050036 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000037 * @link http://codeigniter.com/user_guide/libraries/output.html
38 */
39class CI_Output {
40
David Behler07b53422011-08-15 00:25:06 +020041 /**
42 * Current output string
43 *
44 * @var string
David Behler07b53422011-08-15 00:25:06 +020045 */
Andrey Andreev0f221172012-04-13 14:52:16 +030046 public $final_output;
Timothy Warrenad475052012-04-19 13:21:06 -040047
David Behler07b53422011-08-15 00:25:06 +020048 /**
49 * Cache expiration time
50 *
51 * @var int
David Behler07b53422011-08-15 00:25:06 +020052 */
Timothy Warren40403d22012-04-19 16:38:50 -040053 public $cache_expiration = 0;
Timothy Warrenad475052012-04-19 13:21:06 -040054
David Behler07b53422011-08-15 00:25:06 +020055 /**
56 * List of server headers
57 *
58 * @var array
David Behler07b53422011-08-15 00:25:06 +020059 */
Timothy Warren40403d22012-04-19 16:38:50 -040060 public $headers = array();
Timothy Warrenad475052012-04-19 13:21:06 -040061
David Behler07b53422011-08-15 00:25:06 +020062 /**
63 * List of mime types
64 *
65 * @var array
David Behler07b53422011-08-15 00:25:06 +020066 */
Timothy Warren40403d22012-04-19 16:38:50 -040067 public $mime_types = array();
Timothy Warrenad475052012-04-19 13:21:06 -040068
David Behler07b53422011-08-15 00:25:06 +020069 /**
70 * Determines wether profiler is enabled
71 *
72 * @var book
David Behler07b53422011-08-15 00:25:06 +020073 */
Timothy Warren40403d22012-04-19 16:38:50 -040074 public $enable_profiler = FALSE;
Timothy Warrenad475052012-04-19 13:21:06 -040075
David Behler07b53422011-08-15 00:25:06 +020076 /**
77 * Determines if output compression is enabled
78 *
79 * @var bool
David Behler07b53422011-08-15 00:25:06 +020080 */
Timothy Warren40403d22012-04-19 16:38:50 -040081 protected $_zlib_oc = FALSE;
Timothy Warrenad475052012-04-19 13:21:06 -040082
David Behler07b53422011-08-15 00:25:06 +020083 /**
84 * List of profiler sections
85 *
86 * @var array
David Behler07b53422011-08-15 00:25:06 +020087 */
Phil Sturgeon60ed1a32011-03-08 21:43:54 +000088 protected $_profiler_sections = array();
Timothy Warrenad475052012-04-19 13:21:06 -040089
David Behler07b53422011-08-15 00:25:06 +020090 /**
91 * Whether or not to parse variables like {elapsed_time} and {memory_usage}
92 *
93 * @var bool
David Behler07b53422011-08-15 00:25:06 +020094 */
Timothy Warren40403d22012-04-19 16:38:50 -040095 public $parse_exec_vars = TRUE;
Derek Jonesee71c802010-03-10 10:05:05 -060096
Timothy Warrenad475052012-04-19 13:21:06 -040097 /**
98 * Set up Output class
99 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200100 public function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +0000101 {
Pascal Kriete676e1cd2010-04-09 21:16:16 +0200102 $this->_zlib_oc = @ini_get('zlib.output_compression');
Barry Mienydd671972010-10-04 16:33:58 +0200103
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000104 // Get mime types for later
Andrey Andreev7b53d042012-03-26 23:02:32 +0300105 if (defined('ENVIRONMENT') && file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
Greg Akerd96f8822011-12-27 16:23:47 -0600106 {
107 include APPPATH.'config/'.ENVIRONMENT.'/mimes.php';
108 }
109 else
110 {
111 include APPPATH.'config/mimes.php';
112 }
113
Eric Barnesbb5d4f72011-03-18 13:39:58 -0400114
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000115 $this->mime_types = $mimes;
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200116 log_message('debug', 'Output Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000117 }
Barry Mienydd671972010-10-04 16:33:58 +0200118
Derek Allard2067d1a2008-11-13 22:59:24 +0000119 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200120
Derek Allard2067d1a2008-11-13 22:59:24 +0000121 /**
122 * Get Output
123 *
124 * Returns the current output string
125 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000126 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200127 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200128 public function get_output()
Derek Allard2067d1a2008-11-13 22:59:24 +0000129 {
130 return $this->final_output;
131 }
Barry Mienydd671972010-10-04 16:33:58 +0200132
Derek Allard2067d1a2008-11-13 22:59:24 +0000133 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200134
Derek Allard2067d1a2008-11-13 22:59:24 +0000135 /**
136 * Set Output
137 *
138 * Sets the output string
139 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000140 * @param string
141 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200142 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200143 public function set_output($output)
Derek Allard2067d1a2008-11-13 22:59:24 +0000144 {
145 $this->final_output = $output;
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000146 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000147 }
148
149 // --------------------------------------------------------------------
150
151 /**
152 * Append Output
153 *
154 * Appends data onto the output string
155 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000156 * @param string
157 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200158 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200159 public function append_output($output)
Derek Allard2067d1a2008-11-13 22:59:24 +0000160 {
161 if ($this->final_output == '')
162 {
163 $this->final_output = $output;
164 }
165 else
166 {
167 $this->final_output .= $output;
168 }
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000169
170 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000171 }
172
173 // --------------------------------------------------------------------
174
175 /**
176 * Set Header
177 *
178 * Lets you set a server header which will be outputted with the final display.
179 *
Derek Jones37f4b9c2011-07-01 17:56:50 -0500180 * Note: If a file is cached, headers will not be sent. We need to figure out
Derek Allard2067d1a2008-11-13 22:59:24 +0000181 * how to permit header data to be saved with the cache data...
182 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000183 * @param string
David Behler07b53422011-08-15 00:25:06 +0200184 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +0000185 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200186 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200187 public function set_header($header, $replace = TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000188 {
Pascal Kriete676e1cd2010-04-09 21:16:16 +0200189 // If zlib.output_compression is enabled it will compress the output,
190 // but it will not modify the content-length header to compensate for
191 // the reduction, causing the browser to hang waiting for more data.
192 // We'll just skip content-length in those cases.
Pascal Kriete676e1cd2010-04-09 21:16:16 +0200193 if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) == 0)
194 {
195 return;
196 }
Barry Mienydd671972010-10-04 16:33:58 +0200197
Derek Allard2067d1a2008-11-13 22:59:24 +0000198 $this->headers[] = array($header, $replace);
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000199 return $this;
200 }
201
202 // --------------------------------------------------------------------
203
204 /**
205 * Set Content Type Header
206 *
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000207 * @param string extension of the file we're outputting
208 * @return void
209 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200210 public function set_content_type($mime_type)
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000211 {
212 if (strpos($mime_type, '/') === FALSE)
213 {
214 $extension = ltrim($mime_type, '.');
215
216 // Is this extension supported?
217 if (isset($this->mime_types[$extension]))
218 {
219 $mime_type =& $this->mime_types[$extension];
220
221 if (is_array($mime_type))
222 {
223 $mime_type = current($mime_type);
224 }
225 }
226 }
227
228 $header = 'Content-Type: '.$mime_type;
229
230 $this->headers[] = array($header, TRUE);
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000231 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000232 }
Andrey Andreev00adf1d2012-04-03 12:30:50 +0300233
Songpol Sripaoeiam52fe7bb2012-04-01 11:43:20 +0700234 // --------------------------------------------------------------------
Andrey Andreev00adf1d2012-04-03 12:30:50 +0300235
Songpol Sripaoeiam52fe7bb2012-04-01 11:43:20 +0700236 /**
237 * Get Current Content Type Header
Songpol Sripaoeiam52fe7bb2012-04-01 11:43:20 +0700238 *
Andrey Andreev00adf1d2012-04-03 12:30:50 +0300239 * @return string 'text/html', if not already set
Songpol Sripaoeiam52fe7bb2012-04-01 11:43:20 +0700240 */
Songpol Sripaoeiam614db072012-04-03 01:29:28 +0700241 public function get_content_type()
Songpol Sripaoeiam52fe7bb2012-04-01 11:43:20 +0700242 {
Andrey Andreev00adf1d2012-04-03 12:30:50 +0300243 for ($i = 0, $c = count($this->headers); $i < $c; $i++)
Songpol Sripao-eiam38c0a722012-04-01 20:10:35 +0700244 {
Andrey Andreev00adf1d2012-04-03 12:30:50 +0300245 if (preg_match('/^Content-Type:\s(.+)$/', $this->headers[$i][0], $matches))
Songpol Sripaoeiamb9667012012-04-01 17:13:44 +0700246 {
Andrey Andreev00adf1d2012-04-03 12:30:50 +0300247 return $matches[1];
Songpol Sripaoeiam52fe7bb2012-04-01 11:43:20 +0700248 }
Songpol Sripaoeiamb9667012012-04-01 17:13:44 +0700249 }
Andrey Andreev00adf1d2012-04-03 12:30:50 +0300250
Songpol Sripaoeiamb9667012012-04-01 17:13:44 +0700251 return 'text/html';
Songpol Sripaoeiam52fe7bb2012-04-01 11:43:20 +0700252 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000253
254 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200255
Derek Allard2067d1a2008-11-13 22:59:24 +0000256 /**
257 * Set HTTP Status Header
Derek Jones817163a2009-07-11 17:05:58 +0000258 * moved to Common procedural functions in 1.7.2
Barry Mienydd671972010-10-04 16:33:58 +0200259 *
Andrey Andreev7b53d042012-03-26 23:02:32 +0300260 * @param int the status code
Barry Mienydd671972010-10-04 16:33:58 +0200261 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +0000262 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200263 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200264 public function set_status_header($code = 200, $text = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000265 {
Derek Jones817163a2009-07-11 17:05:58 +0000266 set_status_header($code, $text);
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000267 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000268 }
Barry Mienydd671972010-10-04 16:33:58 +0200269
Derek Allard2067d1a2008-11-13 22:59:24 +0000270 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200271
Derek Allard2067d1a2008-11-13 22:59:24 +0000272 /**
273 * Enable/disable Profiler
274 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000275 * @param bool
276 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200277 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200278 public function enable_profiler($val = TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000279 {
Andrey Andreev7b53d042012-03-26 23:02:32 +0300280 $this->enable_profiler = is_bool($val) ? $val : TRUE;
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000281 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000282 }
Barry Mienydd671972010-10-04 16:33:58 +0200283
Derek Allard2067d1a2008-11-13 22:59:24 +0000284 // --------------------------------------------------------------------
Derek Jonesee71c802010-03-10 10:05:05 -0600285
286 /**
287 * Set Profiler Sections
288 *
289 * Allows override of default / config settings for Profiler section display
290 *
Derek Jonesee71c802010-03-10 10:05:05 -0600291 * @param array
292 * @return void
293 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200294 public function set_profiler_sections($sections)
Derek Jonesee71c802010-03-10 10:05:05 -0600295 {
296 foreach ($sections as $section => $enable)
297 {
Andrey Andreev7b53d042012-03-26 23:02:32 +0300298 $this->_profiler_sections[$section] = ($enable !== FALSE);
Derek Jonesee71c802010-03-10 10:05:05 -0600299 }
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000300
301 return $this;
Derek Jonesee71c802010-03-10 10:05:05 -0600302 }
303
304 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200305
Derek Allard2067d1a2008-11-13 22:59:24 +0000306 /**
307 * Set Cache
308 *
Andrey Andreev7b53d042012-03-26 23:02:32 +0300309 * @param int
Derek Allard2067d1a2008-11-13 22:59:24 +0000310 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200311 */
Michiel Vugteveen0609d582012-01-08 13:26:17 +0100312 public function cache($time)
Derek Allard2067d1a2008-11-13 22:59:24 +0000313 {
Andrey Andreev7b53d042012-03-26 23:02:32 +0300314 $this->cache_expiration = is_numeric($time) ? $time : 0;
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000315 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000316 }
Barry Mienydd671972010-10-04 16:33:58 +0200317
Derek Allard2067d1a2008-11-13 22:59:24 +0000318 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200319
Derek Allard2067d1a2008-11-13 22:59:24 +0000320 /**
321 * Display Output
322 *
323 * All "view" data is automatically put into this variable by the controller class:
324 *
325 * $this->final_output
326 *
327 * This function sends the finalized output data to the browser along
Andrey Andreev7b53d042012-03-26 23:02:32 +0300328 * with any server headers and profile data. It also stops the
Derek Allard2067d1a2008-11-13 22:59:24 +0000329 * benchmark timer so the page rendering speed and memory usage can be shown.
330 *
David Behler07b53422011-08-15 00:25:06 +0200331 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +0000332 * @return mixed
Barry Mienydd671972010-10-04 16:33:58 +0200333 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200334 public function _display($output = '')
Barry Mienydd671972010-10-04 16:33:58 +0200335 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500336 // Note: We use globals because we can't use $CI =& get_instance()
Derek Allard2067d1a2008-11-13 22:59:24 +0000337 // since this function is sometimes called by the caching mechanism,
338 // which happens before the CI super object is available.
339 global $BM, $CFG;
Derek Jonesd7633492010-09-28 13:14:57 -0500340
341 // Grab the super object if we can.
Greg Akercc922102010-11-17 20:25:08 -0600342 if (class_exists('CI_Controller'))
Derek Jonesd7633492010-09-28 13:14:57 -0500343 {
344 $CI =& get_instance();
345 }
346
Derek Allard2067d1a2008-11-13 22:59:24 +0000347 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200348
Derek Allard2067d1a2008-11-13 22:59:24 +0000349 // Set the output data
350 if ($output == '')
351 {
352 $output =& $this->final_output;
353 }
Barry Mienydd671972010-10-04 16:33:58 +0200354
Derek Allard2067d1a2008-11-13 22:59:24 +0000355 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200356
Derek Jones37f4b9c2011-07-01 17:56:50 -0500357 // Do we need to write a cache file? Only if the controller does not have its
Derek Jonesd7633492010-09-28 13:14:57 -0500358 // own _output() method and we are not dealing with a cache file, which we
359 // can determine by the existence of the $CI object above
360 if ($this->cache_expiration > 0 && isset($CI) && ! method_exists($CI, '_output'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000361 {
362 $this->_write_cache($output);
363 }
Barry Mienydd671972010-10-04 16:33:58 +0200364
Derek Allard2067d1a2008-11-13 22:59:24 +0000365 // --------------------------------------------------------------------
366
367 // Parse out the elapsed time and memory usage,
368 // then swap the pseudo-variables with the data
Barry Mienydd671972010-10-04 16:33:58 +0200369
370 $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');
Derek Jones46520492010-03-02 13:53:25 -0600371
372 if ($this->parse_exec_vars === TRUE)
373 {
Andrey Andreev7b53d042012-03-26 23:02:32 +0300374 $memory = function_exists('memory_get_usage') ? round(memory_get_usage()/1024/1024, 2).'MB' : '0';
Barry Mienydd671972010-10-04 16:33:58 +0200375
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200376 $output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output);
Derek Jones46520492010-03-02 13:53:25 -0600377 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000378
379 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200380
Derek Allard2067d1a2008-11-13 22:59:24 +0000381 // Is compression requested?
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200382 if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc == FALSE
383 && extension_loaded('zlib')
384 && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000385 {
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200386 ob_start('ob_gzhandler');
Derek Allard2067d1a2008-11-13 22:59:24 +0000387 }
388
389 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200390
Derek Allard2067d1a2008-11-13 22:59:24 +0000391 // Are there any server headers to send?
392 if (count($this->headers) > 0)
393 {
394 foreach ($this->headers as $header)
395 {
396 @header($header[0], $header[1]);
397 }
Barry Mienydd671972010-10-04 16:33:58 +0200398 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000399
400 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200401
Derek Jonesd7633492010-09-28 13:14:57 -0500402 // Does the $CI object exist?
Derek Allard2067d1a2008-11-13 22:59:24 +0000403 // If not we know we are dealing with a cache file so we'll
404 // simply echo out the data and exit.
Derek Jonesd7633492010-09-28 13:14:57 -0500405 if ( ! isset($CI))
Derek Allard2067d1a2008-11-13 22:59:24 +0000406 {
407 echo $output;
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200408 log_message('debug', 'Final output sent to browser');
409 log_message('debug', 'Total execution time: '.$elapsed);
Derek Allard2067d1a2008-11-13 22:59:24 +0000410 return TRUE;
411 }
Barry Mienydd671972010-10-04 16:33:58 +0200412
Derek Allard2067d1a2008-11-13 22:59:24 +0000413 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200414
Derek Allard2067d1a2008-11-13 22:59:24 +0000415 // Do we need to generate profile data?
416 // If so, load the Profile class and run it.
417 if ($this->enable_profiler == TRUE)
418 {
Barry Mienydd671972010-10-04 16:33:58 +0200419 $CI->load->library('profiler');
Derek Jonesee71c802010-03-10 10:05:05 -0600420 if ( ! empty($this->_profiler_sections))
421 {
422 $CI->profiler->set_sections($this->_profiler_sections);
Barry Mienydd671972010-10-04 16:33:58 +0200423 }
Derek Jonesee71c802010-03-10 10:05:05 -0600424
Derek Allard2067d1a2008-11-13 22:59:24 +0000425 // If the output data contains closing </body> and </html> tags
426 // we will remove them and add them back after we insert the profile data
Andrey Andreevcba20b12012-01-09 10:16:41 +0200427 $output = preg_replace('|</body>.*?</html>|is', '', $output, -1, $count).$CI->profiler->run();
428 if ($count > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000429 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000430 $output .= '</body></html>';
431 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000432 }
Barry Mienydd671972010-10-04 16:33:58 +0200433
Derek Allard2067d1a2008-11-13 22:59:24 +0000434 // Does the controller contain a function named _output()?
Derek Jones37f4b9c2011-07-01 17:56:50 -0500435 // If so send the output there. Otherwise, echo it.
Derek Allard2067d1a2008-11-13 22:59:24 +0000436 if (method_exists($CI, '_output'))
437 {
438 $CI->_output($output);
439 }
440 else
441 {
Andrey Andreevedc87552012-01-09 09:35:10 +0200442 echo $output; // Send it to the browser!
Derek Allard2067d1a2008-11-13 22:59:24 +0000443 }
Barry Mienydd671972010-10-04 16:33:58 +0200444
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200445 log_message('debug', 'Final output sent to browser');
446 log_message('debug', 'Total execution time: '.$elapsed);
Derek Allard2067d1a2008-11-13 22:59:24 +0000447 }
Barry Mienydd671972010-10-04 16:33:58 +0200448
Derek Allard2067d1a2008-11-13 22:59:24 +0000449 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200450
Derek Allard2067d1a2008-11-13 22:59:24 +0000451 /**
452 * Write a Cache File
453 *
David Behler07b53422011-08-15 00:25:06 +0200454 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +0000455 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200456 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200457 public function _write_cache($output)
Derek Allard2067d1a2008-11-13 22:59:24 +0000458 {
Barry Mienydd671972010-10-04 16:33:58 +0200459 $CI =& get_instance();
Derek Allard2067d1a2008-11-13 22:59:24 +0000460 $path = $CI->config->item('cache_path');
Greg Aker2eaa4072010-12-21 11:44:08 -0600461 $cache_path = ($path == '') ? APPPATH.'cache/' : $path;
Barry Mienydd671972010-10-04 16:33:58 +0200462
Derek Allard2067d1a2008-11-13 22:59:24 +0000463 if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
464 {
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200465 log_message('error', 'Unable to write cache file: '.$cache_path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000466 return;
467 }
Barry Mienydd671972010-10-04 16:33:58 +0200468
Derek Allard2067d1a2008-11-13 22:59:24 +0000469 $uri = $CI->config->item('base_url').
470 $CI->config->item('index_page').
471 $CI->uri->uri_string();
Barry Mienydd671972010-10-04 16:33:58 +0200472
Derek Allard2067d1a2008-11-13 22:59:24 +0000473 $cache_path .= md5($uri);
474
475 if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE))
476 {
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200477 log_message('error', 'Unable to write cache file: '.$cache_path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000478 return;
479 }
Barry Mienydd671972010-10-04 16:33:58 +0200480
Derek Allard2067d1a2008-11-13 22:59:24 +0000481 $expire = time() + ($this->cache_expiration * 60);
Barry Mienydd671972010-10-04 16:33:58 +0200482
Derek Allard2067d1a2008-11-13 22:59:24 +0000483 if (flock($fp, LOCK_EX))
484 {
485 fwrite($fp, $expire.'TS--->'.$output);
486 flock($fp, LOCK_UN);
487 }
488 else
489 {
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200490 log_message('error', 'Unable to secure a file lock for file at: '.$cache_path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000491 return;
492 }
493 fclose($fp);
Derek Jones172e1612009-10-13 14:32:48 +0000494 @chmod($cache_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000495
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200496 log_message('debug', 'Cache file written: '.$cache_path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000497 }
498
499 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200500
Derek Allard2067d1a2008-11-13 22:59:24 +0000501 /**
502 * Update/serve a cached file
503 *
David Behler07b53422011-08-15 00:25:06 +0200504 * @param object config class
505 * @param object uri class
Derek Allard2067d1a2008-11-13 22:59:24 +0000506 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200507 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200508 public function _display_cache(&$CFG, &$URI)
Derek Allard2067d1a2008-11-13 22:59:24 +0000509 {
Greg Aker2eaa4072010-12-21 11:44:08 -0600510 $cache_path = ($CFG->item('cache_path') == '') ? APPPATH.'cache/' : $CFG->item('cache_path');
Barry Mienydd671972010-10-04 16:33:58 +0200511
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200512 // Build the file path. The file name is an MD5 hash of the full URI
513 $uri = $CFG->item('base_url').$CFG->item('index_page').$URI->uri_string;
Derek Allard2067d1a2008-11-13 22:59:24 +0000514 $filepath = $cache_path.md5($uri);
Barry Mienydd671972010-10-04 16:33:58 +0200515
Andrey Andreevc90d6512012-01-08 04:35:02 +0200516 if ( ! @file_exists($filepath) OR ! $fp = @fopen($filepath, FOPEN_READ))
Derek Allard2067d1a2008-11-13 22:59:24 +0000517 {
518 return FALSE;
519 }
Barry Mienydd671972010-10-04 16:33:58 +0200520
Derek Allard2067d1a2008-11-13 22:59:24 +0000521 flock($fp, LOCK_SH);
Barry Mienydd671972010-10-04 16:33:58 +0200522
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200523 $cache = (filesize($filepath) > 0) ? fread($fp, filesize($filepath)) : '';
Barry Mienydd671972010-10-04 16:33:58 +0200524
Derek Allard2067d1a2008-11-13 22:59:24 +0000525 flock($fp, LOCK_UN);
526 fclose($fp);
Barry Mienydd671972010-10-04 16:33:58 +0200527
528 // Strip out the embedded timestamp
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200529 if ( ! preg_match('/(\d+TS--->)/', $cache, $match))
Derek Allard2067d1a2008-11-13 22:59:24 +0000530 {
531 return FALSE;
532 }
Barry Mienydd671972010-10-04 16:33:58 +0200533
Derek Allard2067d1a2008-11-13 22:59:24 +0000534 // Has the file expired? If so we'll delete it.
Andrey Andreevc90d6512012-01-08 04:35:02 +0200535 if (time() >= trim(str_replace('TS--->', '', $match[1])) && is_really_writable($cache_path))
Derek Jonesd99e6032010-03-19 19:57:33 -0500536 {
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200537 @unlink($filepath);
538 log_message('debug', 'Cache file has expired. File deleted.');
539 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000540 }
541
542 // Display the cache
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200543 $this->_display(str_replace($match[0], '', $cache));
544 log_message('debug', 'Cache file is current. Sending it to browser.');
Derek Allard2067d1a2008-11-13 22:59:24 +0000545 return TRUE;
546 }
547
Derek Allard2067d1a2008-11-13 22:59:24 +0000548}
Derek Allard2067d1a2008-11-13 22:59:24 +0000549
550/* End of file Output.php */
Andrey Andreev7b53d042012-03-26 23:02:32 +0300551/* Location: ./system/core/Output.php */