blob: 1c3f0d604fb93676d108dbaeacd84a8802b04c1e [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 {
adminb5a651c2006-09-23 17:39:41 +0000126 // Note: We can't use $obj =& _get_instance() since this function
127 // is sometimes called by the caching mechanism, which happens before
128 // it's available. Instead we'll use globals...
129 global $BM, $CFG;
adminc1fa0742006-09-21 23:50:23 +0000130
adminb0dd10f2006-08-25 17:25:49 +0000131 if ($output == '')
132 {
133 $output =& $this->final_output;
134 }
135
admin460f2672006-09-21 02:41:37 +0000136 // Do we need to write a cache file?
adminb0dd10f2006-08-25 17:25:49 +0000137 if ($this->cache_expiration > 0)
138 {
139 $this->_write_cache($output);
140 }
141
admin460f2672006-09-21 02:41:37 +0000142 // Parse out the elapsed time and memory usage, and
143 // swap the pseudo-variables with the data
adminb5a651c2006-09-23 17:39:41 +0000144 $elapsed = $BM->elapsed_time('code_igniter_start', 'code_igniter_end');
adminb0dd10f2006-08-25 17:25:49 +0000145 $memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
146
147 $output = str_replace('{memory_usage}', $memory, $output);
148 $output = str_replace('{elapsed_time}', $elapsed, $output);
149
admin9aaa75e2006-09-21 04:45:20 +0000150 // Is compression requested?
adminb5a651c2006-09-23 17:39:41 +0000151 if ($CFG->item('compress_output') === TRUE)
admin9aaa75e2006-09-21 04:45:20 +0000152 {
153 if (extension_loaded('zlib'))
154 {
155 if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
156 {
157 ob_start('ob_gzhandler');
158 }
159 }
160 }
161
admin460f2672006-09-21 02:41:37 +0000162 // Are there any server headers to send?
163 if (count($this->headers) > 0)
164 {
165 foreach ($this->headers as $header)
166 {
167 @header($header);
168 }
169 }
170
adminc1fa0742006-09-21 23:50:23 +0000171 // Send the finalized output either directly
172 // to the browser or to the user's _output()
173 // function if it exists
adminb5a651c2006-09-23 17:39:41 +0000174 if (function_exists('_get_instance') AND method_exists($obj, '_output'))
adminc1fa0742006-09-21 23:50:23 +0000175 {
176 $obj->_output($output);
177 }
178 else
179 {
180 echo $output; // Send it to the browser!
181 }
adminb0dd10f2006-08-25 17:25:49 +0000182
183 log_message('debug', "Final output sent to browser");
184 log_message('debug', "Total execution time: ".$elapsed);
185 }
186
187 // --------------------------------------------------------------------
188
189 /**
190 * Write a Cache File
191 *
192 * @access public
193 * @return void
194 */
195 function _write_cache($output)
196 {
197 $obj =& get_instance();
198 $path = $obj->config->item('cache_path');
199
200 $cache_path = ($path == '') ? BASEPATH.'cache/' : $path;
201
202 if ( ! is_dir($cache_path) OR ! is_writable($cache_path))
203 {
204 return;
205 }
206
admin1856f582006-09-15 20:48:15 +0000207 $uri = $obj->config->item('base_url').
adminb0dd10f2006-08-25 17:25:49 +0000208 $obj->config->item('index_page').
209 $obj->uri->uri_string();
210
211 $cache_path .= md5($uri);
212
213 if ( ! $fp = @fopen($cache_path, 'wb'))
214 {
215 log_message('error', "Unable to write ache file: ".$cache_path);
216 return;
217 }
218
219 $expire = time() + ($this->cache_expiration * 60);
220
221 flock($fp, LOCK_EX);
222 fwrite($fp, $expire.'TS--->'.$output);
223 flock($fp, LOCK_UN);
224 fclose($fp);
225 @chmod($cache_path, 0777);
226
227 log_message('debug', "Cache file written: ".$cache_path);
228 }
229
230 // --------------------------------------------------------------------
231
232 /**
233 * Update/serve a cached file
234 *
235 * @access public
236 * @return void
237 */
admin15c2bcc2006-09-18 08:17:56 +0000238 function _display_cache(&$CFG, &$RTR)
adminb0dd10f2006-08-25 17:25:49 +0000239 {
admin33de9a12006-09-28 06:50:16 +0000240 $CFG =& _load_class('Config');
241 $RTR =& _load_class('Router');
adminb0dd10f2006-08-25 17:25:49 +0000242
243 $cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path');
244
245 if ( ! is_dir($cache_path) OR ! is_writable($cache_path))
246 {
247 return FALSE;
248 }
249
250 // Build the file path. The file name is an MD5 hash of the full URI
admin15c2bcc2006-09-18 08:17:56 +0000251 $uri = $CFG->item('base_url').
252 $CFG->item('index_page').
253 $RTR->uri_string;
admin1856f582006-09-15 20:48:15 +0000254
adminb0dd10f2006-08-25 17:25:49 +0000255 $filepath = $cache_path.md5($uri);
256
257 if ( ! @file_exists($filepath))
258 {
259 return FALSE;
260 }
261
262 if ( ! $fp = @fopen($filepath, 'rb'))
263 {
264 return FALSE;
265 }
266
267 flock($fp, LOCK_SH);
268
269 $cache = '';
270 if (filesize($filepath) > 0)
271 {
272 $cache = fread($fp, filesize($filepath));
273 }
274
275 flock($fp, LOCK_UN);
276 fclose($fp);
277
278 // Strip out the embedded timestamp
279 if ( ! preg_match("/(\d+TS--->)/", $cache, $match))
280 {
281 return FALSE;
282 }
283
284 // Has the file expired? If so we'll delete it.
285 if (time() >= trim(str_replace('TS--->', '', $match['1'])))
286 {
287 @unlink($filepath);
288 log_message('debug', "Cache file has expired. File deleted");
289 return FALSE;
290 }
291
292 // Display the cache
293 $this->_display(str_replace($match['0'], '', $cache));
294 log_message('debug', "Cache file is current. Sending it to browser.");
295 return TRUE;
296 }
297
298}
299// END Output Class
300?>