blob: 9727a184fd4bdf011fe03be45f5ce3ac6f0fc860 [file] [log] [blame]
Derek Jones37f4b9c2011-07-01 17:56:50 -05001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Greg Aker741de1c2010-11-10 14:52:57 -06005 * An open source application development framework for PHP 5.1.6 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
8 *
9 * Licensed under the Open Software License version 3.0
10 *
11 * 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
21 * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
22 * @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
28// ------------------------------------------------------------------------
29
30/**
31 * Output Class
32 *
33 * Responsible for sending final output to browser
34 *
35 * @package CodeIgniter
36 * @subpackage Libraries
37 * @category Output
Derek Jonesf4a4bd82011-10-20 12:18:42 -050038 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000039 * @link http://codeigniter.com/user_guide/libraries/output.html
40 */
41class CI_Output {
42
David Behler07b53422011-08-15 00:25:06 +020043 /**
44 * Current output string
45 *
46 * @var string
47 * @access protected
48 */
Phil Sturgeon60ed1a32011-03-08 21:43:54 +000049 protected $final_output;
David Behler07b53422011-08-15 00:25:06 +020050 /**
51 * Cache expiration time
52 *
53 * @var int
54 * @access protected
55 */
Phil Sturgeon60ed1a32011-03-08 21:43:54 +000056 protected $cache_expiration = 0;
David Behler07b53422011-08-15 00:25:06 +020057 /**
58 * List of server headers
59 *
60 * @var array
61 * @access protected
62 */
Phil Sturgeon60ed1a32011-03-08 21:43:54 +000063 protected $headers = array();
David Behler07b53422011-08-15 00:25:06 +020064 /**
65 * List of mime types
66 *
67 * @var array
68 * @access protected
69 */
70 protected $mime_types = array();
71 /**
72 * Determines wether profiler is enabled
73 *
74 * @var book
75 * @access protected
76 */
Phil Sturgeon60ed1a32011-03-08 21:43:54 +000077 protected $enable_profiler = FALSE;
David Behler07b53422011-08-15 00:25:06 +020078 /**
79 * Determines if output compression is enabled
80 *
81 * @var bool
82 * @access protected
83 */
Phil Sturgeon60ed1a32011-03-08 21:43:54 +000084 protected $_zlib_oc = FALSE;
David Behler07b53422011-08-15 00:25:06 +020085 /**
86 * List of profiler sections
87 *
88 * @var array
89 * @access protected
90 */
Phil Sturgeon60ed1a32011-03-08 21:43:54 +000091 protected $_profiler_sections = array();
David Behler07b53422011-08-15 00:25:06 +020092 /**
93 * Whether or not to parse variables like {elapsed_time} and {memory_usage}
94 *
95 * @var bool
96 * @access protected
97 */
98 protected $parse_exec_vars = TRUE;
Derek Jonesee71c802010-03-10 10:05:05 -060099
David Behler07b53422011-08-15 00:25:06 +0200100 /**
101 * Constructor
102 *
103 */
Greg Akera9263282010-11-10 15:26:43 -0600104 function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +0000105 {
Pascal Kriete676e1cd2010-04-09 21:16:16 +0200106 $this->_zlib_oc = @ini_get('zlib.output_compression');
Barry Mienydd671972010-10-04 16:33:58 +0200107
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000108 // Get mime types for later
Greg Aker3a746652011-04-19 10:59:47 -0500109 if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
bubbafoley0ea04142011-03-17 14:55:41 -0500110 {
Greg Aker03abee32011-12-25 00:31:29 -0600111 include APPPATH.'config/'.ENVIRONMENT.'/mimes.php';
bubbafoley0ea04142011-03-17 14:55:41 -0500112 }
113 else
114 {
Greg Aker3a746652011-04-19 10:59:47 -0500115 include APPPATH.'config/mimes.php';
bubbafoley0ea04142011-03-17 14:55:41 -0500116 }
Eric Barnesbb5d4f72011-03-18 13:39:58 -0400117
118
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000119 $this->mime_types = $mimes;
Eric Barnesbb5d4f72011-03-18 13:39:58 -0400120
Derek Allard2067d1a2008-11-13 22:59:24 +0000121 log_message('debug', "Output Class Initialized");
122 }
Barry Mienydd671972010-10-04 16:33:58 +0200123
Derek Allard2067d1a2008-11-13 22:59:24 +0000124 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200125
Derek Allard2067d1a2008-11-13 22:59:24 +0000126 /**
127 * Get Output
128 *
129 * Returns the current output string
130 *
131 * @access public
132 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200133 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000134 function get_output()
135 {
136 return $this->final_output;
137 }
Barry Mienydd671972010-10-04 16:33:58 +0200138
Derek Allard2067d1a2008-11-13 22:59:24 +0000139 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200140
Derek Allard2067d1a2008-11-13 22:59:24 +0000141 /**
142 * Set Output
143 *
144 * Sets the output string
145 *
146 * @access public
147 * @param string
148 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200149 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000150 function set_output($output)
151 {
152 $this->final_output = $output;
Eric Barnesbb5d4f72011-03-18 13:39:58 -0400153
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000154 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000155 }
156
157 // --------------------------------------------------------------------
158
159 /**
160 * Append Output
161 *
162 * Appends data onto the output string
163 *
164 * @access public
165 * @param string
166 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200167 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000168 function append_output($output)
169 {
170 if ($this->final_output == '')
171 {
172 $this->final_output = $output;
173 }
174 else
175 {
176 $this->final_output .= $output;
177 }
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000178
179 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000180 }
181
182 // --------------------------------------------------------------------
183
184 /**
185 * Set Header
186 *
187 * Lets you set a server header which will be outputted with the final display.
188 *
Derek Jones37f4b9c2011-07-01 17:56:50 -0500189 * Note: If a file is cached, headers will not be sent. We need to figure out
Derek Allard2067d1a2008-11-13 22:59:24 +0000190 * how to permit header data to be saved with the cache data...
191 *
192 * @access public
193 * @param string
David Behler07b53422011-08-15 00:25:06 +0200194 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +0000195 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200196 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000197 function set_header($header, $replace = TRUE)
198 {
Pascal Kriete676e1cd2010-04-09 21:16:16 +0200199 // If zlib.output_compression is enabled it will compress the output,
200 // but it will not modify the content-length header to compensate for
201 // the reduction, causing the browser to hang waiting for more data.
202 // We'll just skip content-length in those cases.
Barry Mienydd671972010-10-04 16:33:58 +0200203
Pascal Kriete676e1cd2010-04-09 21:16:16 +0200204 if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) == 0)
205 {
206 return;
207 }
Barry Mienydd671972010-10-04 16:33:58 +0200208
Derek Allard2067d1a2008-11-13 22:59:24 +0000209 $this->headers[] = array($header, $replace);
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000210
211 return $this;
212 }
213
214 // --------------------------------------------------------------------
215
216 /**
217 * Set Content Type Header
218 *
219 * @access public
220 * @param string extension of the file we're outputting
221 * @return void
222 */
223 function set_content_type($mime_type)
224 {
225 if (strpos($mime_type, '/') === FALSE)
226 {
227 $extension = ltrim($mime_type, '.');
228
229 // Is this extension supported?
230 if (isset($this->mime_types[$extension]))
231 {
232 $mime_type =& $this->mime_types[$extension];
233
234 if (is_array($mime_type))
235 {
236 $mime_type = current($mime_type);
237 }
238 }
239 }
240
241 $header = 'Content-Type: '.$mime_type;
242
243 $this->headers[] = array($header, TRUE);
Eric Barnesbb5d4f72011-03-18 13:39:58 -0400244
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000245 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000246 }
247
248 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200249
Derek Allard2067d1a2008-11-13 22:59:24 +0000250 /**
251 * Set HTTP Status Header
Derek Jones817163a2009-07-11 17:05:58 +0000252 * moved to Common procedural functions in 1.7.2
Barry Mienydd671972010-10-04 16:33:58 +0200253 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000254 * @access public
Barry Mienydd671972010-10-04 16:33:58 +0200255 * @param int the status code
256 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +0000257 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200258 */
Derek Jones46520492010-03-02 13:53:25 -0600259 function set_status_header($code = 200, $text = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000260 {
Derek Jones817163a2009-07-11 17:05:58 +0000261 set_status_header($code, $text);
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000262
263 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000264 }
Barry Mienydd671972010-10-04 16:33:58 +0200265
Derek Allard2067d1a2008-11-13 22:59:24 +0000266 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200267
Derek Allard2067d1a2008-11-13 22:59:24 +0000268 /**
269 * Enable/disable Profiler
270 *
271 * @access public
272 * @param bool
273 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200274 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000275 function enable_profiler($val = TRUE)
276 {
277 $this->enable_profiler = (is_bool($val)) ? $val : TRUE;
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000278
279 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000280 }
Barry Mienydd671972010-10-04 16:33:58 +0200281
Derek Allard2067d1a2008-11-13 22:59:24 +0000282 // --------------------------------------------------------------------
Derek Jonesee71c802010-03-10 10:05:05 -0600283
284 /**
285 * Set Profiler Sections
286 *
287 * Allows override of default / config settings for Profiler section display
288 *
289 * @access public
290 * @param array
291 * @return void
292 */
293 function set_profiler_sections($sections)
294 {
295 foreach ($sections as $section => $enable)
296 {
297 $this->_profiler_sections[$section] = ($enable !== FALSE) ? TRUE : FALSE;
298 }
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000299
300 return $this;
Derek Jonesee71c802010-03-10 10:05:05 -0600301 }
302
303 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200304
Derek Allard2067d1a2008-11-13 22:59:24 +0000305 /**
306 * Set Cache
307 *
308 * @access public
309 * @param integer
310 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200311 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000312 function cache($time)
313 {
314 $this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000315
316 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000317 }
Barry Mienydd671972010-10-04 16:33:58 +0200318
Derek Allard2067d1a2008-11-13 22:59:24 +0000319 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200320
Derek Allard2067d1a2008-11-13 22:59:24 +0000321 /**
322 * Display Output
323 *
324 * All "view" data is automatically put into this variable by the controller class:
325 *
326 * $this->final_output
327 *
328 * This function sends the finalized output data to the browser along
Derek Jones37f4b9c2011-07-01 17:56:50 -0500329 * with any server headers and profile data. It also stops the
Derek Allard2067d1a2008-11-13 22:59:24 +0000330 * benchmark timer so the page rendering speed and memory usage can be shown.
331 *
332 * @access public
David Behler07b53422011-08-15 00:25:06 +0200333 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +0000334 * @return mixed
Barry Mienydd671972010-10-04 16:33:58 +0200335 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000336 function _display($output = '')
Barry Mienydd671972010-10-04 16:33:58 +0200337 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500338 // Note: We use globals because we can't use $CI =& get_instance()
Derek Allard2067d1a2008-11-13 22:59:24 +0000339 // since this function is sometimes called by the caching mechanism,
340 // which happens before the CI super object is available.
341 global $BM, $CFG;
Derek Jonesd7633492010-09-28 13:14:57 -0500342
343 // Grab the super object if we can.
Greg Akercc922102010-11-17 20:25:08 -0600344 if (class_exists('CI_Controller'))
Derek Jonesd7633492010-09-28 13:14:57 -0500345 {
346 $CI =& get_instance();
347 }
348
Derek Allard2067d1a2008-11-13 22:59:24 +0000349 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200350
Derek Allard2067d1a2008-11-13 22:59:24 +0000351 // Set the output data
352 if ($output == '')
353 {
354 $output =& $this->final_output;
355 }
Barry Mienydd671972010-10-04 16:33:58 +0200356
Derek Allard2067d1a2008-11-13 22:59:24 +0000357 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200358
Derek Jones37f4b9c2011-07-01 17:56:50 -0500359 // Do we need to write a cache file? Only if the controller does not have its
Derek Jonesd7633492010-09-28 13:14:57 -0500360 // own _output() method and we are not dealing with a cache file, which we
361 // can determine by the existence of the $CI object above
362 if ($this->cache_expiration > 0 && isset($CI) && ! method_exists($CI, '_output'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000363 {
364 $this->_write_cache($output);
365 }
Barry Mienydd671972010-10-04 16:33:58 +0200366
Derek Allard2067d1a2008-11-13 22:59:24 +0000367 // --------------------------------------------------------------------
368
369 // Parse out the elapsed time and memory usage,
370 // then swap the pseudo-variables with the data
Barry Mienydd671972010-10-04 16:33:58 +0200371
372 $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');
Derek Jones46520492010-03-02 13:53:25 -0600373
374 if ($this->parse_exec_vars === TRUE)
375 {
376 $memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
Barry Mienydd671972010-10-04 16:33:58 +0200377
Derek Jones46520492010-03-02 13:53:25 -0600378 $output = str_replace('{elapsed_time}', $elapsed, $output);
379 $output = str_replace('{memory_usage}', $memory, $output);
380 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000381
382 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200383
Derek Allard2067d1a2008-11-13 22:59:24 +0000384 // Is compression requested?
Pascal Kriete676e1cd2010-04-09 21:16:16 +0200385 if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc == FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000386 {
387 if (extension_loaded('zlib'))
388 {
389 if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
390 {
391 ob_start('ob_gzhandler');
392 }
393 }
394 }
395
396 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200397
Derek Allard2067d1a2008-11-13 22:59:24 +0000398 // Are there any server headers to send?
399 if (count($this->headers) > 0)
400 {
401 foreach ($this->headers as $header)
402 {
403 @header($header[0], $header[1]);
404 }
Barry Mienydd671972010-10-04 16:33:58 +0200405 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000406
407 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200408
Derek Jonesd7633492010-09-28 13:14:57 -0500409 // Does the $CI object exist?
Derek Allard2067d1a2008-11-13 22:59:24 +0000410 // If not we know we are dealing with a cache file so we'll
411 // simply echo out the data and exit.
Derek Jonesd7633492010-09-28 13:14:57 -0500412 if ( ! isset($CI))
Derek Allard2067d1a2008-11-13 22:59:24 +0000413 {
414 echo $output;
415 log_message('debug', "Final output sent to browser");
416 log_message('debug', "Total execution time: ".$elapsed);
417 return TRUE;
418 }
Barry Mienydd671972010-10-04 16:33:58 +0200419
Derek Allard2067d1a2008-11-13 22:59:24 +0000420 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200421
Derek Allard2067d1a2008-11-13 22:59:24 +0000422 // Do we need to generate profile data?
423 // If so, load the Profile class and run it.
424 if ($this->enable_profiler == TRUE)
425 {
Barry Mienydd671972010-10-04 16:33:58 +0200426 $CI->load->library('profiler');
427
Derek Jonesee71c802010-03-10 10:05:05 -0600428 if ( ! empty($this->_profiler_sections))
429 {
430 $CI->profiler->set_sections($this->_profiler_sections);
Barry Mienydd671972010-10-04 16:33:58 +0200431 }
Derek Jonesee71c802010-03-10 10:05:05 -0600432
Derek Allard2067d1a2008-11-13 22:59:24 +0000433 // If the output data contains closing </body> and </html> tags
434 // we will remove them and add them back after we insert the profile data
435 if (preg_match("|</body>.*?</html>|is", $output))
436 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500437 $output = preg_replace("|</body>.*?</html>|is", '', $output);
Derek Allard2067d1a2008-11-13 22:59:24 +0000438 $output .= $CI->profiler->run();
439 $output .= '</body></html>';
440 }
441 else
442 {
443 $output .= $CI->profiler->run();
444 }
445 }
Barry Mienydd671972010-10-04 16:33:58 +0200446
Derek Allard2067d1a2008-11-13 22:59:24 +0000447 // --------------------------------------------------------------------
448
449 // Does the controller contain a function named _output()?
Derek Jones37f4b9c2011-07-01 17:56:50 -0500450 // If so send the output there. Otherwise, echo it.
Derek Allard2067d1a2008-11-13 22:59:24 +0000451 if (method_exists($CI, '_output'))
452 {
453 $CI->_output($output);
454 }
455 else
456 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500457 echo $output; // Send it to the browser!
Derek Allard2067d1a2008-11-13 22:59:24 +0000458 }
Barry Mienydd671972010-10-04 16:33:58 +0200459
Derek Allard2067d1a2008-11-13 22:59:24 +0000460 log_message('debug', "Final output sent to browser");
Barry Mienydd671972010-10-04 16:33:58 +0200461 log_message('debug', "Total execution time: ".$elapsed);
Derek Allard2067d1a2008-11-13 22:59:24 +0000462 }
Barry Mienydd671972010-10-04 16:33:58 +0200463
Derek Allard2067d1a2008-11-13 22:59:24 +0000464 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200465
Derek Allard2067d1a2008-11-13 22:59:24 +0000466 /**
467 * Write a Cache File
468 *
469 * @access public
David Behler07b53422011-08-15 00:25:06 +0200470 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +0000471 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200472 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000473 function _write_cache($output)
474 {
Barry Mienydd671972010-10-04 16:33:58 +0200475 $CI =& get_instance();
Derek Allard2067d1a2008-11-13 22:59:24 +0000476 $path = $CI->config->item('cache_path');
Barry Mienydd671972010-10-04 16:33:58 +0200477
Greg Aker2eaa4072010-12-21 11:44:08 -0600478 $cache_path = ($path == '') ? APPPATH.'cache/' : $path;
Barry Mienydd671972010-10-04 16:33:58 +0200479
Derek Allard2067d1a2008-11-13 22:59:24 +0000480 if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
481 {
Greg Akera7f5a942010-09-14 17:20:53 -0500482 log_message('error', "Unable to write cache file: ".$cache_path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000483 return;
484 }
Barry Mienydd671972010-10-04 16:33:58 +0200485
Derek Allard2067d1a2008-11-13 22:59:24 +0000486 $uri = $CI->config->item('base_url').
487 $CI->config->item('index_page').
488 $CI->uri->uri_string();
Barry Mienydd671972010-10-04 16:33:58 +0200489
Derek Allard2067d1a2008-11-13 22:59:24 +0000490 $cache_path .= md5($uri);
491
492 if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE))
493 {
494 log_message('error', "Unable to write cache file: ".$cache_path);
495 return;
496 }
Barry Mienydd671972010-10-04 16:33:58 +0200497
Derek Allard2067d1a2008-11-13 22:59:24 +0000498 $expire = time() + ($this->cache_expiration * 60);
Barry Mienydd671972010-10-04 16:33:58 +0200499
Derek Allard2067d1a2008-11-13 22:59:24 +0000500 if (flock($fp, LOCK_EX))
501 {
502 fwrite($fp, $expire.'TS--->'.$output);
503 flock($fp, LOCK_UN);
504 }
505 else
506 {
507 log_message('error', "Unable to secure a file lock for file at: ".$cache_path);
508 return;
509 }
510 fclose($fp);
Derek Jones172e1612009-10-13 14:32:48 +0000511 @chmod($cache_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000512
513 log_message('debug', "Cache file written: ".$cache_path);
514 }
515
516 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200517
Derek Allard2067d1a2008-11-13 22:59:24 +0000518 /**
519 * Update/serve a cached file
520 *
521 * @access public
David Behler07b53422011-08-15 00:25:06 +0200522 * @param object config class
523 * @param object uri class
Derek Allard2067d1a2008-11-13 22:59:24 +0000524 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200525 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000526 function _display_cache(&$CFG, &$URI)
527 {
Greg Aker2eaa4072010-12-21 11:44:08 -0600528 $cache_path = ($CFG->item('cache_path') == '') ? APPPATH.'cache/' : $CFG->item('cache_path');
Barry Mienydd671972010-10-04 16:33:58 +0200529
Derek Jones37f4b9c2011-07-01 17:56:50 -0500530 // Build the file path. The file name is an MD5 hash of the full URI
Derek Allard2067d1a2008-11-13 22:59:24 +0000531 $uri = $CFG->item('base_url').
532 $CFG->item('index_page').
533 $URI->uri_string;
Barry Mienydd671972010-10-04 16:33:58 +0200534
Derek Allard2067d1a2008-11-13 22:59:24 +0000535 $filepath = $cache_path.md5($uri);
Barry Mienydd671972010-10-04 16:33:58 +0200536
Derek Allard2067d1a2008-11-13 22:59:24 +0000537 if ( ! @file_exists($filepath))
538 {
539 return FALSE;
540 }
Barry Mienydd671972010-10-04 16:33:58 +0200541
Derek Allard2067d1a2008-11-13 22:59:24 +0000542 if ( ! $fp = @fopen($filepath, FOPEN_READ))
543 {
544 return FALSE;
545 }
Barry Mienydd671972010-10-04 16:33:58 +0200546
Derek Allard2067d1a2008-11-13 22:59:24 +0000547 flock($fp, LOCK_SH);
Barry Mienydd671972010-10-04 16:33:58 +0200548
Derek Allard2067d1a2008-11-13 22:59:24 +0000549 $cache = '';
550 if (filesize($filepath) > 0)
551 {
552 $cache = fread($fp, filesize($filepath));
553 }
Barry Mienydd671972010-10-04 16:33:58 +0200554
Derek Allard2067d1a2008-11-13 22:59:24 +0000555 flock($fp, LOCK_UN);
556 fclose($fp);
Barry Mienydd671972010-10-04 16:33:58 +0200557
558 // Strip out the embedded timestamp
Derek Allard2067d1a2008-11-13 22:59:24 +0000559 if ( ! preg_match("/(\d+TS--->)/", $cache, $match))
560 {
561 return FALSE;
562 }
Barry Mienydd671972010-10-04 16:33:58 +0200563
Derek Allard2067d1a2008-11-13 22:59:24 +0000564 // Has the file expired? If so we'll delete it.
565 if (time() >= trim(str_replace('TS--->', '', $match['1'])))
Derek Jonesd99e6032010-03-19 19:57:33 -0500566 {
567 if (is_really_writable($cache_path))
568 {
569 @unlink($filepath);
570 log_message('debug', "Cache file has expired. File deleted");
Barry Mienydd671972010-10-04 16:33:58 +0200571 return FALSE;
Derek Jonesd99e6032010-03-19 19:57:33 -0500572 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000573 }
574
575 // Display the cache
576 $this->_display(str_replace($match['0'], '', $cache));
Barry Mienydd671972010-10-04 16:33:58 +0200577 log_message('debug', "Cache file is current. Sending it to browser.");
Derek Allard2067d1a2008-11-13 22:59:24 +0000578 return TRUE;
579 }
580
581
582}
583// END Output Class
584
585/* End of file Output.php */
Derek Jonesc68dfbf2010-03-02 12:59:23 -0600586/* Location: ./system/core/Output.php */