blob: 4a3adb858227ea096bd0e94fa9fa3f7792faaf38 [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 {
126 $BM =& _load_class('CI_Benchmark');
127
128 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
adminb0dd10f2006-08-25 17:25:49 +0000141 $elapsed = $BM->elapsed_time('code_igniter_start', 'code_igniter_end');
142 $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?
148 $CFG =& _load_class('CI_Config');
149 if ($CFG->item('compress_output') === TRUE)
150 {
151 if (extension_loaded('zlib'))
152 {
153 if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
154 {
155 ob_start('ob_gzhandler');
156 }
157 }
158 }
159
admin460f2672006-09-21 02:41:37 +0000160 // Are there any server headers to send?
161 if (count($this->headers) > 0)
162 {
163 foreach ($this->headers as $header)
164 {
165 @header($header);
166 }
167 }
168
169 // Send it to the browser!
adminb0dd10f2006-08-25 17:25:49 +0000170 echo $output;
171
172 log_message('debug', "Final output sent to browser");
173 log_message('debug', "Total execution time: ".$elapsed);
174 }
175
176 // --------------------------------------------------------------------
177
178 /**
179 * Write a Cache File
180 *
181 * @access public
182 * @return void
183 */
184 function _write_cache($output)
185 {
186 $obj =& get_instance();
187 $path = $obj->config->item('cache_path');
188
189 $cache_path = ($path == '') ? BASEPATH.'cache/' : $path;
190
191 if ( ! is_dir($cache_path) OR ! is_writable($cache_path))
192 {
193 return;
194 }
195
admin1856f582006-09-15 20:48:15 +0000196 $uri = $obj->config->item('base_url').
adminb0dd10f2006-08-25 17:25:49 +0000197 $obj->config->item('index_page').
198 $obj->uri->uri_string();
199
200 $cache_path .= md5($uri);
201
202 if ( ! $fp = @fopen($cache_path, 'wb'))
203 {
204 log_message('error', "Unable to write ache file: ".$cache_path);
205 return;
206 }
207
208 $expire = time() + ($this->cache_expiration * 60);
209
210 flock($fp, LOCK_EX);
211 fwrite($fp, $expire.'TS--->'.$output);
212 flock($fp, LOCK_UN);
213 fclose($fp);
214 @chmod($cache_path, 0777);
215
216 log_message('debug', "Cache file written: ".$cache_path);
217 }
218
219 // --------------------------------------------------------------------
220
221 /**
222 * Update/serve a cached file
223 *
224 * @access public
225 * @return void
226 */
admin15c2bcc2006-09-18 08:17:56 +0000227 function _display_cache(&$CFG, &$RTR)
adminb0dd10f2006-08-25 17:25:49 +0000228 {
229 $CFG =& _load_class('CI_Config');
230 $RTR =& _load_class('CI_Router');
231
232 $cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path');
233
234 if ( ! is_dir($cache_path) OR ! is_writable($cache_path))
235 {
236 return FALSE;
237 }
238
239 // Build the file path. The file name is an MD5 hash of the full URI
admin15c2bcc2006-09-18 08:17:56 +0000240 $uri = $CFG->item('base_url').
241 $CFG->item('index_page').
242 $RTR->uri_string;
admin1856f582006-09-15 20:48:15 +0000243
adminb0dd10f2006-08-25 17:25:49 +0000244 $filepath = $cache_path.md5($uri);
245
246 if ( ! @file_exists($filepath))
247 {
248 return FALSE;
249 }
250
251 if ( ! $fp = @fopen($filepath, 'rb'))
252 {
253 return FALSE;
254 }
255
256 flock($fp, LOCK_SH);
257
258 $cache = '';
259 if (filesize($filepath) > 0)
260 {
261 $cache = fread($fp, filesize($filepath));
262 }
263
264 flock($fp, LOCK_UN);
265 fclose($fp);
266
267 // Strip out the embedded timestamp
268 if ( ! preg_match("/(\d+TS--->)/", $cache, $match))
269 {
270 return FALSE;
271 }
272
273 // Has the file expired? If so we'll delete it.
274 if (time() >= trim(str_replace('TS--->', '', $match['1'])))
275 {
276 @unlink($filepath);
277 log_message('debug', "Cache file has expired. File deleted");
278 return FALSE;
279 }
280
281 // Display the cache
282 $this->_display(str_replace($match['0'], '', $cache));
283 log_message('debug', "Cache file is current. Sending it to browser.");
284 return TRUE;
285 }
286
287}
288// END Output Class
289?>