blob: ec3660c6c7522b4d7bc96dc15c97b54bb6e22538 [file] [log] [blame]
adminb0dd10f2006-08-25 17:25:49 +00001<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * Code Igniter
4 *
5 * An open source application development framework for PHP 4.3.2 or newer
6 *
7 * @package CodeIgniter
8 * @author Rick Ellis
9 * @copyright Copyright (c) 2006, pMachine, Inc.
10 * @license http://www.codeignitor.com/user_guide/license.html
11 * @link http://www.codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * Output Class
20 *
21 * Responsible for sending final output to browser
22 *
23 * @package CodeIgniter
24 * @subpackage Libraries
25 * @category Output
26 * @author Rick Ellis
27 * @link http://www.codeigniter.com/user_guide/libraries/output.html
28 */
29class CI_Output {
30
31 var $final_output;
32 var $cache_expiration = 0;
admin460f2672006-09-21 02:41:37 +000033 var $headers = array();
adminb0dd10f2006-08-25 17:25:49 +000034
35 function CI_Output()
36 {
37 log_message('debug', "Output Class Initialized");
38 }
39
40 // --------------------------------------------------------------------
41
42 /**
43 * Get Output
44 *
45 * Returns the current output string
46 *
47 * @access public
48 * @return string
49 */
50 function get_output()
51 {
52 return $this->final_output;
53 }
54
55 // --------------------------------------------------------------------
56
57 /**
58 * Set Output
59 *
60 * Sets the output string
61 *
62 * @access public
63 * @param string
64 * @return void
65 */
66 function set_output($output)
67 {
68 $this->final_output = $output;
69 }
admin460f2672006-09-21 02:41:37 +000070
71 // --------------------------------------------------------------------
72
73 /**
74 * Set Header
75 *
76 * Lets you set a server header which will be outputted with the final display.
77 *
78 * Note: If a file is cached, headers will not be sent. We need to figure out
79 * how to permit header data to be saved with the cache data...
80 *
81 * @access public
82 * @param string
83 * @return void
84 */
85 function set_header($header)
86 {
87 $this->headers[] = $header;
88 }
adminb0dd10f2006-08-25 17:25:49 +000089
90 // --------------------------------------------------------------------
91
92 /**
93 * Set Cache
94 *
95 * @access public
96 * @param integer
97 * @return void
98 */
99 function cache($time)
100 {
admin1cf89aa2006-09-03 18:24:39 +0000101 $this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;
adminb0dd10f2006-08-25 17:25:49 +0000102 }
103
104 // --------------------------------------------------------------------
105
106 /**
107 * Display Output
108 *
109 * All "view" data is automatically put into this variable
110 * by the controller class:
111 *
112 * $this->final_output
113 *
114 * This function simply echos the variable out. It also does the following:
115 *
116 * Stops the benchmark timer so the page rendering speed can be shown.
117 *
118 * Determines if the "memory_get_usage' function is available so that
119 * the memory usage can be shown.
120 *
121 * @access public
122 * @return void
123 */
124 function _display($output = '')
125 {
adminc1fa0742006-09-21 23:50:23 +0000126 $obj =& get_instance();
127
adminb0dd10f2006-08-25 17:25:49 +0000128 if ($output == '')
129 {
130 $output =& $this->final_output;
131 }
132
admin460f2672006-09-21 02:41:37 +0000133 // Do we need to write a cache file?
adminb0dd10f2006-08-25 17:25:49 +0000134 if ($this->cache_expiration > 0)
135 {
136 $this->_write_cache($output);
137 }
138
admin460f2672006-09-21 02:41:37 +0000139 // Parse out the elapsed time and memory usage, and
140 // swap the pseudo-variables with the data
adminc1fa0742006-09-21 23:50:23 +0000141 $elapsed = $obj->benchmark->elapsed_time('code_igniter_start', 'code_igniter_end');
adminb0dd10f2006-08-25 17:25:49 +0000142 $memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
143
144 $output = str_replace('{memory_usage}', $memory, $output);
145 $output = str_replace('{elapsed_time}', $elapsed, $output);
146
admin9aaa75e2006-09-21 04:45:20 +0000147 // Is compression requested?
adminc1fa0742006-09-21 23:50:23 +0000148 if ($obj->config->item('compress_output') === TRUE)
admin9aaa75e2006-09-21 04:45:20 +0000149 {
150 if (extension_loaded('zlib'))
151 {
152 if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
153 {
154 ob_start('ob_gzhandler');
155 }
156 }
157 }
158
admin460f2672006-09-21 02:41:37 +0000159 // Are there any server headers to send?
160 if (count($this->headers) > 0)
161 {
162 foreach ($this->headers as $header)
163 {
164 @header($header);
165 }
166 }
167
adminc1fa0742006-09-21 23:50:23 +0000168 // Send the finalized output either directly
169 // to the browser or to the user's _output()
170 // function if it exists
171 if (method_exists($obj, '_output'))
172 {
173 $obj->_output($output);
174 }
175 else
176 {
177 echo $output; // Send it to the browser!
178 }
adminb0dd10f2006-08-25 17:25:49 +0000179
180 log_message('debug', "Final output sent to browser");
181 log_message('debug', "Total execution time: ".$elapsed);
182 }
183
184 // --------------------------------------------------------------------
185
186 /**
187 * Write a Cache File
188 *
189 * @access public
190 * @return void
191 */
192 function _write_cache($output)
193 {
194 $obj =& get_instance();
195 $path = $obj->config->item('cache_path');
196
197 $cache_path = ($path == '') ? BASEPATH.'cache/' : $path;
198
199 if ( ! is_dir($cache_path) OR ! is_writable($cache_path))
200 {
201 return;
202 }
203
admin1856f582006-09-15 20:48:15 +0000204 $uri = $obj->config->item('base_url').
adminb0dd10f2006-08-25 17:25:49 +0000205 $obj->config->item('index_page').
206 $obj->uri->uri_string();
207
208 $cache_path .= md5($uri);
209
210 if ( ! $fp = @fopen($cache_path, 'wb'))
211 {
212 log_message('error', "Unable to write ache file: ".$cache_path);
213 return;
214 }
215
216 $expire = time() + ($this->cache_expiration * 60);
217
218 flock($fp, LOCK_EX);
219 fwrite($fp, $expire.'TS--->'.$output);
220 flock($fp, LOCK_UN);
221 fclose($fp);
222 @chmod($cache_path, 0777);
223
224 log_message('debug', "Cache file written: ".$cache_path);
225 }
226
227 // --------------------------------------------------------------------
228
229 /**
230 * Update/serve a cached file
231 *
232 * @access public
233 * @return void
234 */
admin15c2bcc2006-09-18 08:17:56 +0000235 function _display_cache(&$CFG, &$RTR)
adminb0dd10f2006-08-25 17:25:49 +0000236 {
237 $CFG =& _load_class('CI_Config');
238 $RTR =& _load_class('CI_Router');
239
240 $cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path');
241
242 if ( ! is_dir($cache_path) OR ! is_writable($cache_path))
243 {
244 return FALSE;
245 }
246
247 // Build the file path. The file name is an MD5 hash of the full URI
admin15c2bcc2006-09-18 08:17:56 +0000248 $uri = $CFG->item('base_url').
249 $CFG->item('index_page').
250 $RTR->uri_string;
admin1856f582006-09-15 20:48:15 +0000251
adminb0dd10f2006-08-25 17:25:49 +0000252 $filepath = $cache_path.md5($uri);
253
254 if ( ! @file_exists($filepath))
255 {
256 return FALSE;
257 }
258
259 if ( ! $fp = @fopen($filepath, 'rb'))
260 {
261 return FALSE;
262 }
263
264 flock($fp, LOCK_SH);
265
266 $cache = '';
267 if (filesize($filepath) > 0)
268 {
269 $cache = fread($fp, filesize($filepath));
270 }
271
272 flock($fp, LOCK_UN);
273 fclose($fp);
274
275 // Strip out the embedded timestamp
276 if ( ! preg_match("/(\d+TS--->)/", $cache, $match))
277 {
278 return FALSE;
279 }
280
281 // Has the file expired? If so we'll delete it.
282 if (time() >= trim(str_replace('TS--->', '', $match['1'])))
283 {
284 @unlink($filepath);
285 log_message('debug', "Cache file has expired. File deleted");
286 return FALSE;
287 }
288
289 // Display the cache
290 $this->_display(str_replace($match['0'], '', $cache));
291 log_message('debug', "Cache file is current. Sending it to browser.");
292 return TRUE;
293 }
294
295}
296// END Output Class
297?>