1 <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
5 * An open source application development framework for PHP 4.3.2 or newer
8 * @author ExpressionEngine Dev Team
9 * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc.
10 * @license http://codeigniter.com/user_guide/license.html
11 * @link http://codeigniter.com
16 // ------------------------------------------------------------------------
21 * Responsible for sending final output to browser
23 * @package CodeIgniter
24 * @subpackage Libraries
26 * @author ExpressionEngine Dev Team
27 * @link http://codeigniter.com/user_guide/libraries/output.html
32 var $cache_expiration = 0;
33 var $headers = array();
34 var $enable_profiler = FALSE;
39 log_message('debug', "Output Class Initialized");
42 // --------------------------------------------------------------------
47 * Returns the current output string
54 return $this->final_output;
57 // --------------------------------------------------------------------
62 * Sets the output string
68 function set_output($output)
70 $this->final_output = $output;
73 // --------------------------------------------------------------------
78 * Appends data onto the output string
84 function append_output($output)
86 if ($this->final_output == '')
88 $this->final_output = $output;
92 $this->final_output .= $output;
96 // --------------------------------------------------------------------
101 * Lets you set a server header which will be outputted with the final display.
103 * Note: If a file is cached, headers will not be sent. We need to figure out
104 * how to permit header data to be saved with the cache data...
110 function set_header($header, $replace = TRUE)
112 $this->headers[] = array($header, $replace);
115 // --------------------------------------------------------------------
118 * Set HTTP Status Header
119 * moved to Common procedural functions in 1.7.2
122 * @param int the status code
126 function set_status_header($code = '200', $text = '')
128 set_status_header($code, $text);
131 // --------------------------------------------------------------------
134 * Enable/disable Profiler
140 function enable_profiler($val = TRUE)
142 $this->enable_profiler = (is_bool($val)) ? $val : TRUE;
145 // --------------------------------------------------------------------
154 function cache($time)
156 $this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;
159 // --------------------------------------------------------------------
164 * All "view" data is automatically put into this variable by the controller class:
166 * $this->final_output
168 * This function sends the finalized output data to the browser along
169 * with any server headers and profile data. It also stops the
170 * benchmark timer so the page rendering speed and memory usage can be shown.
175 function _display($output = '')
177 // Note: We use globals because we can't use $CI =& get_instance()
178 // since this function is sometimes called by the caching mechanism,
179 // which happens before the CI super object is available.
182 // --------------------------------------------------------------------
184 // Set the output data
187 $output =& $this->final_output;
190 // --------------------------------------------------------------------
192 // Do we need to write a cache file?
193 if ($this->cache_expiration > 0)
195 $this->_write_cache($output);
198 // --------------------------------------------------------------------
200 // Parse out the elapsed time and memory usage,
201 // then swap the pseudo-variables with the data
203 $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');
204 $output = str_replace('{elapsed_time}', $elapsed, $output);
206 $memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
207 $output = str_replace('{memory_usage}', $memory, $output);
209 // --------------------------------------------------------------------
211 // Is compression requested?
212 if ($CFG->item('compress_output') === TRUE)
214 if (extension_loaded('zlib'))
216 if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
218 ob_start('ob_gzhandler');
223 // --------------------------------------------------------------------
225 // Are there any server headers to send?
226 if (count($this->headers) > 0)
228 foreach ($this->headers as $header)
230 @header($header[0], $header[1]);
234 // --------------------------------------------------------------------
236 // Does the get_instance() function exist?
237 // If not we know we are dealing with a cache file so we'll
238 // simply echo out the data and exit.
239 if ( ! function_exists('get_instance'))
242 log_message('debug', "Final output sent to browser");
243 log_message('debug', "Total execution time: ".$elapsed);
247 // --------------------------------------------------------------------
249 // Grab the super object. We'll need it in a moment...
250 $CI =& get_instance();
252 // Do we need to generate profile data?
253 // If so, load the Profile class and run it.
254 if ($this->enable_profiler == TRUE)
256 $CI->load->library('profiler');
258 // If the output data contains closing </body> and </html> tags
259 // we will remove them and add them back after we insert the profile data
260 if (preg_match("|</body>.*?</html>|is", $output))
262 $output = preg_replace("|</body>.*?</html>|is", '', $output);
263 $output .= $CI->profiler->run();
264 $output .= '</body></html>';
268 $output .= $CI->profiler->run();
272 // --------------------------------------------------------------------
274 // Does the controller contain a function named _output()?
275 // If so send the output there. Otherwise, echo it.
276 if (method_exists($CI, '_output'))
278 $CI->_output($output);
282 echo $output; // Send it to the browser!
285 log_message('debug', "Final output sent to browser");
286 log_message('debug', "Total execution time: ".$elapsed);
289 // --------------------------------------------------------------------
297 function _write_cache($output)
299 $CI =& get_instance();
300 $path = $CI->config->item('cache_path');
302 $cache_path = ($path == '') ? BASEPATH.'cache/' : $path;
304 if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
309 $uri = $CI->config->item('base_url').
310 $CI->config->item('index_page').
311 $CI->uri->uri_string();
313 $cache_path .= md5($uri);
315 if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE))
317 log_message('error', "Unable to write cache file: ".$cache_path);
321 $expire = time() + ($this->cache_expiration * 60);
323 if (flock($fp, LOCK_EX))
325 fwrite($fp, $expire.'TS--->'.$output);
330 log_message('error', "Unable to secure a file lock for file at: ".$cache_path);
334 @chmod($cache_path, DIR_WRITE_MODE);
336 log_message('debug', "Cache file written: ".$cache_path);
339 // --------------------------------------------------------------------
342 * Update/serve a cached file
347 function _display_cache(&$CFG, &$URI)
349 $cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path');
351 if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
356 // Build the file path. The file name is an MD5 hash of the full URI
357 $uri = $CFG->item('base_url').
358 $CFG->item('index_page').
361 $filepath = $cache_path.md5($uri);
363 if ( ! @file_exists($filepath))
368 if ( ! $fp = @fopen($filepath, FOPEN_READ))
376 if (filesize($filepath) > 0)
378 $cache = fread($fp, filesize($filepath));
384 // Strip out the embedded timestamp
385 if ( ! preg_match("/(\d+TS--->)/", $cache, $match))
390 // Has the file expired? If so we'll delete it.
391 if (time() >= trim(str_replace('TS--->', '', $match['1'])))
394 log_message('debug', "Cache file has expired. File deleted");
399 $this->_display(str_replace($match['0'], '', $cache));
400 log_message('debug', "Cache file is current. Sending it to browser.");
408 /* End of file Output.php */
409 /* Location: ./system/libraries/Output.php */