blob: 6312ccd86d59274e0317d23f12ebbb937c81c788 [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreev1f5fbb62012-01-07 20:53:29 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev1f5fbb62012-01-07 20:53:29 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * 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
Greg Aker0defe5d2012-01-01 18:46:41 -060021 * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @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 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000028
Derek Allard2067d1a2008-11-13 22:59:24 +000029/**
30 * Output Class
31 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030032 * Responsible for sending final output to the browser.
Derek Allard2067d1a2008-11-13 22:59:24 +000033 *
34 * @package CodeIgniter
35 * @subpackage Libraries
36 * @category Output
Derek Jonesf4a4bd82011-10-20 12:18:42 -050037 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000038 * @link http://codeigniter.com/user_guide/libraries/output.html
39 */
40class CI_Output {
41
David Behler07b53422011-08-15 00:25:06 +020042 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030043 * Final output string
David Behler07b53422011-08-15 00:25:06 +020044 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030045 * @var string
David Behler07b53422011-08-15 00:25:06 +020046 */
Andrey Andreev0f221172012-04-13 14:52:16 +030047 public $final_output;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030048
David Behler07b53422011-08-15 00:25:06 +020049 /**
50 * Cache expiration time
51 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030052 * @var int
David Behler07b53422011-08-15 00:25:06 +020053 */
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030054 public $cache_expiration = 0;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030055
David Behler07b53422011-08-15 00:25:06 +020056 /**
57 * List of server headers
58 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030059 * @var array
David Behler07b53422011-08-15 00:25:06 +020060 */
Timothy Warren48a7fbb2012-04-23 11:58:16 -040061 public $headers = array();
Andrey Andreev92ebfb62012-05-17 12:49:24 +030062
David Behler07b53422011-08-15 00:25:06 +020063 /**
64 * List of mime types
65 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030066 * @var array
David Behler07b53422011-08-15 00:25:06 +020067 */
Andrey Andreev6ef498b2012-06-05 22:01:58 +030068 public $mimes = array();
Andrey Andreev92ebfb62012-05-17 12:49:24 +030069
David Behler07b53422011-08-15 00:25:06 +020070 /**
Thor (atiredmachine)242115c2012-01-24 23:08:11 -080071 * Mime-type for the current page
72 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030073 * @var string
Thor (atiredmachine)242115c2012-01-24 23:08:11 -080074 */
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030075 protected $mime_type = 'text/html';
Andrey Andreev0140ddd2012-06-16 01:12:56 +030076
Thor (atiredmachine)242115c2012-01-24 23:08:11 -080077 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030078 * Enable Profiler flag
David Behler07b53422011-08-15 00:25:06 +020079 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030080 * @var bool
David Behler07b53422011-08-15 00:25:06 +020081 */
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030082 public $enable_profiler = FALSE;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030083
David Behler07b53422011-08-15 00:25:06 +020084 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030085 * zLib output compression flag
David Behler07b53422011-08-15 00:25:06 +020086 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030087 * @var bool
David Behler07b53422011-08-15 00:25:06 +020088 */
Andrey Andreev0140ddd2012-06-16 01:12:56 +030089 protected $_zlib_oc = FALSE;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030090
David Behler07b53422011-08-15 00:25:06 +020091 /**
92 * List of profiler sections
93 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030094 * @var array
David Behler07b53422011-08-15 00:25:06 +020095 */
Timothy Warren48a7fbb2012-04-23 11:58:16 -040096 protected $_profiler_sections = array();
Andrey Andreev92ebfb62012-05-17 12:49:24 +030097
David Behler07b53422011-08-15 00:25:06 +020098 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030099 * Parse markers flag
David Behler07b53422011-08-15 00:25:06 +0200100 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300101 * Whether or not to parse variables like {elapsed_time} and {memory_usage}.
102 *
103 * @var bool
David Behler07b53422011-08-15 00:25:06 +0200104 */
Timothy Warren48a7fbb2012-04-23 11:58:16 -0400105 public $parse_exec_vars = TRUE;
Derek Jonesee71c802010-03-10 10:05:05 -0600106
Timothy Warrenad475052012-04-19 13:21:06 -0400107 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300108 * Class constructor
109 *
110 * Determines whether zLib output compression will be used.
Andrey Andreev92ebfb62012-05-17 12:49:24 +0300111 *
112 * @return void
Timothy Warrenad475052012-04-19 13:21:06 -0400113 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200114 public function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +0000115 {
Andrey Andreev9ba661b2012-06-04 14:44:34 +0300116 $this->_zlib_oc = (bool) @ini_get('zlib.output_compression');
Barry Mienydd671972010-10-04 16:33:58 +0200117
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000118 // Get mime types for later
Andrey Andreev6ef498b2012-06-05 22:01:58 +0300119 $this->mimes =& get_mimes();
Greg Akerd96f8822011-12-27 16:23:47 -0600120
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200121 log_message('debug', 'Output Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000122 }
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 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300129 * Returns the current output string.
Derek Allard2067d1a2008-11-13 22:59:24 +0000130 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000131 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200132 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200133 public function get_output()
Derek Allard2067d1a2008-11-13 22:59:24 +0000134 {
135 return $this->final_output;
136 }
Barry Mienydd671972010-10-04 16:33:58 +0200137
Derek Allard2067d1a2008-11-13 22:59:24 +0000138 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200139
Derek Allard2067d1a2008-11-13 22:59:24 +0000140 /**
141 * Set Output
142 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300143 * Sets the output string.
Derek Allard2067d1a2008-11-13 22:59:24 +0000144 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300145 * @param string $output Output data
146 * @return object $this
Barry Mienydd671972010-10-04 16:33:58 +0200147 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200148 public function set_output($output)
Derek Allard2067d1a2008-11-13 22:59:24 +0000149 {
150 $this->final_output = $output;
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000151 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000152 }
153
154 // --------------------------------------------------------------------
155
156 /**
157 * Append Output
158 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300159 * Appends data onto the output string.
Derek Allard2067d1a2008-11-13 22:59:24 +0000160 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300161 * @param string $output Data to append
162 * @return object $this
Barry Mienydd671972010-10-04 16:33:58 +0200163 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200164 public function append_output($output)
Derek Allard2067d1a2008-11-13 22:59:24 +0000165 {
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300166 if (empty($this->final_output))
Derek Allard2067d1a2008-11-13 22:59:24 +0000167 {
168 $this->final_output = $output;
169 }
170 else
171 {
172 $this->final_output .= $output;
173 }
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000174
175 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000176 }
177
178 // --------------------------------------------------------------------
179
180 /**
181 * Set Header
182 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300183 * Lets you set a server header which will be sent with the final output.
Derek Allard2067d1a2008-11-13 22:59:24 +0000184 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300185 * Note: If a file is cached, headers will not be sent.
186 * @todo We need to figure out how to permit headers to be cached.
Derek Allard2067d1a2008-11-13 22:59:24 +0000187 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300188 * @param string $header Header
189 * @param bool $replace Whether to replace the old header value, if already set
190 * @return object $this
Barry Mienydd671972010-10-04 16:33:58 +0200191 */
Andrey Andreev44dc50e2012-10-28 13:30:21 +0200192 public function set_header($header, $replace = TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000193 {
Pascal Kriete676e1cd2010-04-09 21:16:16 +0200194 // If zlib.output_compression is enabled it will compress the output,
195 // but it will not modify the content-length header to compensate for
196 // the reduction, causing the browser to hang waiting for more data.
197 // We'll just skip content-length in those cases.
Alex Bilbieed944a32012-06-02 11:07:47 +0100198 if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) === 0)
Pascal Kriete676e1cd2010-04-09 21:16:16 +0200199 {
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300200 return $this;
Pascal Kriete676e1cd2010-04-09 21:16:16 +0200201 }
Barry Mienydd671972010-10-04 16:33:58 +0200202
Derek Allard2067d1a2008-11-13 22:59:24 +0000203 $this->headers[] = array($header, $replace);
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000204 return $this;
205 }
206
207 // --------------------------------------------------------------------
208
209 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300210 * Set Content-Type Header
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000211 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300212 * @param string $mime_type Extension of the file we're outputting
213 * @param string $charset Character set (default: NULL)
214 * @return object $this
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000215 */
Andrey Andreev47b67332012-06-06 15:58:05 +0300216 public function set_content_type($mime_type, $charset = NULL)
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000217 {
218 if (strpos($mime_type, '/') === FALSE)
219 {
220 $extension = ltrim($mime_type, '.');
221
222 // Is this extension supported?
Andrey Andreev6ef498b2012-06-05 22:01:58 +0300223 if (isset($this->mimes[$extension]))
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000224 {
Andrey Andreev6ef498b2012-06-05 22:01:58 +0300225 $mime_type =& $this->mimes[$extension];
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000226
227 if (is_array($mime_type))
228 {
229 $mime_type = current($mime_type);
230 }
231 }
232 }
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300233
Thor (atiredmachine)242115c2012-01-24 23:08:11 -0800234 $this->mime_type = $mime_type;
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000235
Andrey Andreev47b67332012-06-06 15:58:05 +0300236 if (empty($charset))
237 {
238 $charset = config_item('charset');
239 }
240
241 $header = 'Content-Type: '.$mime_type
242 .(empty($charset) ? NULL : '; charset='.strtolower($charset));
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000243
244 $this->headers[] = array($header, TRUE);
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000245 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000246 }
Andrey Andreev00adf1d2012-04-03 12:30:50 +0300247
Songpol Sripaoeiam52fe7bb2012-04-01 11:43:20 +0700248 // --------------------------------------------------------------------
Andrey Andreev00adf1d2012-04-03 12:30:50 +0300249
Songpol Sripaoeiam52fe7bb2012-04-01 11:43:20 +0700250 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300251 * Get Current Content-Type Header
Songpol Sripaoeiam52fe7bb2012-04-01 11:43:20 +0700252 *
Andrey Andreev00adf1d2012-04-03 12:30:50 +0300253 * @return string 'text/html', if not already set
Songpol Sripaoeiam52fe7bb2012-04-01 11:43:20 +0700254 */
Songpol Sripaoeiam614db072012-04-03 01:29:28 +0700255 public function get_content_type()
Songpol Sripaoeiam52fe7bb2012-04-01 11:43:20 +0700256 {
Andrey Andreev00adf1d2012-04-03 12:30:50 +0300257 for ($i = 0, $c = count($this->headers); $i < $c; $i++)
Songpol Sripao-eiam38c0a722012-04-01 20:10:35 +0700258 {
Andrey Andreev7a7ad782012-11-12 17:21:01 +0200259 if (sscanf($this->headers[$i][0], 'Content-Type: %s', $content_type) === 1)
Songpol Sripaoeiamb9667012012-04-01 17:13:44 +0700260 {
Andrey Andreev7a7ad782012-11-12 17:21:01 +0200261 return $content_type;
Songpol Sripaoeiam52fe7bb2012-04-01 11:43:20 +0700262 }
Songpol Sripaoeiamb9667012012-04-01 17:13:44 +0700263 }
Andrey Andreev00adf1d2012-04-03 12:30:50 +0300264
Songpol Sripaoeiamb9667012012-04-01 17:13:44 +0700265 return 'text/html';
Songpol Sripaoeiam52fe7bb2012-04-01 11:43:20 +0700266 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000267
268 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200269
Derek Allard2067d1a2008-11-13 22:59:24 +0000270 /**
271 * Set HTTP Status Header
Barry Mienydd671972010-10-04 16:33:58 +0200272 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300273 * As of version 1.7.2, this is an alias for common function
274 * set_status_header().
275 *
276 * @param int $code Status code (default: 200)
277 * @param string $text Optional message
278 * @return object $this
Barry Mienydd671972010-10-04 16:33:58 +0200279 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200280 public function set_status_header($code = 200, $text = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000281 {
Derek Jones817163a2009-07-11 17:05:58 +0000282 set_status_header($code, $text);
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000283 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000284 }
Barry Mienydd671972010-10-04 16:33:58 +0200285
Derek Allard2067d1a2008-11-13 22:59:24 +0000286 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200287
Derek Allard2067d1a2008-11-13 22:59:24 +0000288 /**
289 * Enable/disable Profiler
290 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300291 * @param bool $val TRUE to enable or FALSE to disable
292 * @return object $this
Barry Mienydd671972010-10-04 16:33:58 +0200293 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200294 public function enable_profiler($val = TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000295 {
Andrey Andreev7b53d042012-03-26 23:02:32 +0300296 $this->enable_profiler = is_bool($val) ? $val : TRUE;
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000297 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000298 }
Barry Mienydd671972010-10-04 16:33:58 +0200299
Derek Allard2067d1a2008-11-13 22:59:24 +0000300 // --------------------------------------------------------------------
Derek Jonesee71c802010-03-10 10:05:05 -0600301
302 /**
303 * Set Profiler Sections
304 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300305 * Allows override of default/config settings for
306 * Profiler section display.
Derek Jonesee71c802010-03-10 10:05:05 -0600307 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300308 * @param array $sections Profiler sections
309 * @return object $this
Derek Jonesee71c802010-03-10 10:05:05 -0600310 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200311 public function set_profiler_sections($sections)
Derek Jonesee71c802010-03-10 10:05:05 -0600312 {
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300313 if (isset($sections['query_toggle_count']))
314 {
315 $this->_profiler_sections['query_toggle_count'] = (int) $sections['query_toggle_count'];
316 unset($sections['query_toggle_count']);
317 }
318
Derek Jonesee71c802010-03-10 10:05:05 -0600319 foreach ($sections as $section => $enable)
320 {
Andrey Andreev7b53d042012-03-26 23:02:32 +0300321 $this->_profiler_sections[$section] = ($enable !== FALSE);
Derek Jonesee71c802010-03-10 10:05:05 -0600322 }
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000323
324 return $this;
Derek Jonesee71c802010-03-10 10:05:05 -0600325 }
326
327 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200328
Derek Allard2067d1a2008-11-13 22:59:24 +0000329 /**
330 * Set Cache
331 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300332 * @param int $time Cache expiration time in seconds
333 * @return object $this
Barry Mienydd671972010-10-04 16:33:58 +0200334 */
Michiel Vugteveen0609d582012-01-08 13:26:17 +0100335 public function cache($time)
Derek Allard2067d1a2008-11-13 22:59:24 +0000336 {
Andrey Andreev7b53d042012-03-26 23:02:32 +0300337 $this->cache_expiration = is_numeric($time) ? $time : 0;
Phil Sturgeon60ed1a32011-03-08 21:43:54 +0000338 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000339 }
Barry Mienydd671972010-10-04 16:33:58 +0200340
Derek Allard2067d1a2008-11-13 22:59:24 +0000341 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200342
Derek Allard2067d1a2008-11-13 22:59:24 +0000343 /**
344 * Display Output
345 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300346 * Processes sends the sends finalized output data to the browser along
347 * with any server headers and profile data. It also stops benchmark
348 * timers so the page rendering speed and memory usage can be shown.
Derek Allard2067d1a2008-11-13 22:59:24 +0000349 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300350 * Note: All "view" data is automatically put into $this->final_output
351 * by controller class.
Derek Allard2067d1a2008-11-13 22:59:24 +0000352 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300353 * @uses CI_Output::$final_output
354 * @param string $output Output data override
355 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200356 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200357 public function _display($output = '')
Barry Mienydd671972010-10-04 16:33:58 +0200358 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500359 // Note: We use globals because we can't use $CI =& get_instance()
Derek Allard2067d1a2008-11-13 22:59:24 +0000360 // since this function is sometimes called by the caching mechanism,
361 // which happens before the CI super object is available.
362 global $BM, $CFG;
Derek Jonesd7633492010-09-28 13:14:57 -0500363
364 // Grab the super object if we can.
Greg Akercc922102010-11-17 20:25:08 -0600365 if (class_exists('CI_Controller'))
Derek Jonesd7633492010-09-28 13:14:57 -0500366 {
367 $CI =& get_instance();
368 }
369
Derek Allard2067d1a2008-11-13 22:59:24 +0000370 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200371
Derek Allard2067d1a2008-11-13 22:59:24 +0000372 // Set the output data
Alex Bilbieed944a32012-06-02 11:07:47 +0100373 if ($output === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000374 {
375 $output =& $this->final_output;
376 }
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300377
Thor (atiredmachine)63678a22012-01-24 16:56:01 -0800378 // --------------------------------------------------------------------
379
380 // Is minify requested?
381 if ($CFG->item('minify_output') === TRUE)
382 {
Thor (atiredmachine)5528c0e2012-01-25 01:02:28 -0800383 $output = $this->minify($output, $this->mime_type);
Thor (atiredmachine)63678a22012-01-24 16:56:01 -0800384 }
385
Derek Allard2067d1a2008-11-13 22:59:24 +0000386 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200387
vkeranova8349bc2012-10-27 18:07:59 +0300388 // Do we need to write a cache file? Only if the controller does not have its
Derek Jonesd7633492010-09-28 13:14:57 -0500389 // own _output() method and we are not dealing with a cache file, which we
390 // can determine by the existence of the $CI object above
391 if ($this->cache_expiration > 0 && isset($CI) && ! method_exists($CI, '_output'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000392 {
393 $this->_write_cache($output);
394 }
Barry Mienydd671972010-10-04 16:33:58 +0200395
Derek Allard2067d1a2008-11-13 22:59:24 +0000396 // --------------------------------------------------------------------
397
398 // Parse out the elapsed time and memory usage,
399 // then swap the pseudo-variables with the data
Barry Mienydd671972010-10-04 16:33:58 +0200400
401 $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');
Derek Jones46520492010-03-02 13:53:25 -0600402
403 if ($this->parse_exec_vars === TRUE)
404 {
Andrey Andreevc839d282012-06-07 14:35:27 +0300405 $memory = round(memory_get_usage() / 1024 / 1024, 2).'MB';
Barry Mienydd671972010-10-04 16:33:58 +0200406
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200407 $output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output);
Derek Jones46520492010-03-02 13:53:25 -0600408 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000409
410 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200411
Derek Allard2067d1a2008-11-13 22:59:24 +0000412 // Is compression requested?
Alex Bilbieed944a32012-06-02 11:07:47 +0100413 if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc === FALSE
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200414 && extension_loaded('zlib')
415 && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000416 {
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200417 ob_start('ob_gzhandler');
Derek Allard2067d1a2008-11-13 22:59:24 +0000418 }
419
420 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200421
Derek Allard2067d1a2008-11-13 22:59:24 +0000422 // Are there any server headers to send?
423 if (count($this->headers) > 0)
424 {
425 foreach ($this->headers as $header)
426 {
427 @header($header[0], $header[1]);
428 }
Barry Mienydd671972010-10-04 16:33:58 +0200429 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000430
431 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200432
Derek Jonesd7633492010-09-28 13:14:57 -0500433 // Does the $CI object exist?
Derek Allard2067d1a2008-11-13 22:59:24 +0000434 // If not we know we are dealing with a cache file so we'll
435 // simply echo out the data and exit.
Derek Jonesd7633492010-09-28 13:14:57 -0500436 if ( ! isset($CI))
Derek Allard2067d1a2008-11-13 22:59:24 +0000437 {
438 echo $output;
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200439 log_message('debug', 'Final output sent to browser');
440 log_message('debug', 'Total execution time: '.$elapsed);
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300441 return;
Derek Allard2067d1a2008-11-13 22:59:24 +0000442 }
Barry Mienydd671972010-10-04 16:33:58 +0200443
Derek Allard2067d1a2008-11-13 22:59:24 +0000444 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200445
Derek Allard2067d1a2008-11-13 22:59:24 +0000446 // Do we need to generate profile data?
447 // If so, load the Profile class and run it.
Alex Bilbieed944a32012-06-02 11:07:47 +0100448 if ($this->enable_profiler === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000449 {
Barry Mienydd671972010-10-04 16:33:58 +0200450 $CI->load->library('profiler');
Derek Jonesee71c802010-03-10 10:05:05 -0600451 if ( ! empty($this->_profiler_sections))
452 {
453 $CI->profiler->set_sections($this->_profiler_sections);
Barry Mienydd671972010-10-04 16:33:58 +0200454 }
Derek Jonesee71c802010-03-10 10:05:05 -0600455
Derek Allard2067d1a2008-11-13 22:59:24 +0000456 // If the output data contains closing </body> and </html> tags
457 // we will remove them and add them back after we insert the profile data
Andrey Andreevcba20b12012-01-09 10:16:41 +0200458 $output = preg_replace('|</body>.*?</html>|is', '', $output, -1, $count).$CI->profiler->run();
459 if ($count > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000460 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000461 $output .= '</body></html>';
462 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000463 }
Barry Mienydd671972010-10-04 16:33:58 +0200464
Derek Allard2067d1a2008-11-13 22:59:24 +0000465 // Does the controller contain a function named _output()?
Derek Jones37f4b9c2011-07-01 17:56:50 -0500466 // If so send the output there. Otherwise, echo it.
Derek Allard2067d1a2008-11-13 22:59:24 +0000467 if (method_exists($CI, '_output'))
468 {
469 $CI->_output($output);
470 }
471 else
472 {
Andrey Andreevedc87552012-01-09 09:35:10 +0200473 echo $output; // Send it to the browser!
Derek Allard2067d1a2008-11-13 22:59:24 +0000474 }
Barry Mienydd671972010-10-04 16:33:58 +0200475
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200476 log_message('debug', 'Final output sent to browser');
477 log_message('debug', 'Total execution time: '.$elapsed);
Derek Allard2067d1a2008-11-13 22:59:24 +0000478 }
Barry Mienydd671972010-10-04 16:33:58 +0200479
Derek Allard2067d1a2008-11-13 22:59:24 +0000480 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200481
Derek Allard2067d1a2008-11-13 22:59:24 +0000482 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300483 * Write Cache
Derek Allard2067d1a2008-11-13 22:59:24 +0000484 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300485 * @param string $output Output data to cache
Derek Allard2067d1a2008-11-13 22:59:24 +0000486 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200487 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200488 public function _write_cache($output)
Derek Allard2067d1a2008-11-13 22:59:24 +0000489 {
Barry Mienydd671972010-10-04 16:33:58 +0200490 $CI =& get_instance();
Derek Allard2067d1a2008-11-13 22:59:24 +0000491 $path = $CI->config->item('cache_path');
Alex Bilbieed944a32012-06-02 11:07:47 +0100492 $cache_path = ($path === '') ? APPPATH.'cache/' : $path;
Barry Mienydd671972010-10-04 16:33:58 +0200493
Derek Allard2067d1a2008-11-13 22:59:24 +0000494 if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
495 {
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200496 log_message('error', 'Unable to write cache file: '.$cache_path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000497 return;
498 }
Barry Mienydd671972010-10-04 16:33:58 +0200499
Derek Allard2067d1a2008-11-13 22:59:24 +0000500 $uri = $CI->config->item('base_url').
501 $CI->config->item('index_page').
502 $CI->uri->uri_string();
Barry Mienydd671972010-10-04 16:33:58 +0200503
Derek Allard2067d1a2008-11-13 22:59:24 +0000504 $cache_path .= md5($uri);
505
506 if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE))
507 {
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200508 log_message('error', 'Unable to write cache file: '.$cache_path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000509 return;
510 }
Barry Mienydd671972010-10-04 16:33:58 +0200511
Derek Allard2067d1a2008-11-13 22:59:24 +0000512 $expire = time() + ($this->cache_expiration * 60);
Barry Mienydd671972010-10-04 16:33:58 +0200513
Derek Allard2067d1a2008-11-13 22:59:24 +0000514 if (flock($fp, LOCK_EX))
515 {
516 fwrite($fp, $expire.'TS--->'.$output);
517 flock($fp, LOCK_UN);
518 }
519 else
520 {
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200521 log_message('error', 'Unable to secure a file lock for file at: '.$cache_path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000522 return;
523 }
524 fclose($fp);
Derek Jones172e1612009-10-13 14:32:48 +0000525 @chmod($cache_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000526
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200527 log_message('debug', 'Cache file written: '.$cache_path);
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300528
Thor (atiredmachine)c8efb802012-01-24 13:33:39 -0800529 // Send HTTP cache-control headers to browser to match file cache settings.
Thor (atiredmachine)5528c0e2012-01-25 01:02:28 -0800530 $this->set_cache_header($_SERVER['REQUEST_TIME'], $expire);
Derek Allard2067d1a2008-11-13 22:59:24 +0000531 }
532
533 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200534
Derek Allard2067d1a2008-11-13 22:59:24 +0000535 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300536 * Update/serve cached output
Derek Allard2067d1a2008-11-13 22:59:24 +0000537 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300538 * @uses CI_Config
539 * @uses CI_URI
540 *
541 * @param object &$CFG CI_Config class instance
542 * @param object &$URI CI_URI class instance
543 * @return bool TRUE on success or FALSE on failure
Barry Mienydd671972010-10-04 16:33:58 +0200544 */
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200545 public function _display_cache(&$CFG, &$URI)
Derek Allard2067d1a2008-11-13 22:59:24 +0000546 {
Alex Bilbieed944a32012-06-02 11:07:47 +0100547 $cache_path = ($CFG->item('cache_path') === '') ? APPPATH.'cache/' : $CFG->item('cache_path');
Barry Mienydd671972010-10-04 16:33:58 +0200548
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200549 // Build the file path. The file name is an MD5 hash of the full URI
550 $uri = $CFG->item('base_url').$CFG->item('index_page').$URI->uri_string;
Derek Allard2067d1a2008-11-13 22:59:24 +0000551 $filepath = $cache_path.md5($uri);
Barry Mienydd671972010-10-04 16:33:58 +0200552
Andrey Andreevc90d6512012-01-08 04:35:02 +0200553 if ( ! @file_exists($filepath) OR ! $fp = @fopen($filepath, FOPEN_READ))
Derek Allard2067d1a2008-11-13 22:59:24 +0000554 {
555 return FALSE;
556 }
Barry Mienydd671972010-10-04 16:33:58 +0200557
Derek Allard2067d1a2008-11-13 22:59:24 +0000558 flock($fp, LOCK_SH);
Barry Mienydd671972010-10-04 16:33:58 +0200559
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200560 $cache = (filesize($filepath) > 0) ? fread($fp, filesize($filepath)) : '';
Barry Mienydd671972010-10-04 16:33:58 +0200561
Derek Allard2067d1a2008-11-13 22:59:24 +0000562 flock($fp, LOCK_UN);
563 fclose($fp);
Barry Mienydd671972010-10-04 16:33:58 +0200564
565 // Strip out the embedded timestamp
vlakoff239e0e52012-09-16 19:16:33 +0200566 if ( ! preg_match('/^(\d+)TS--->/', $cache, $match))
Derek Allard2067d1a2008-11-13 22:59:24 +0000567 {
568 return FALSE;
569 }
Barry Mienydd671972010-10-04 16:33:58 +0200570
Thor (atiredmachine)c8efb802012-01-24 13:33:39 -0800571 $last_modified = filemtime($cache_path);
vlakoff239e0e52012-09-16 19:16:33 +0200572 $expire = $match[1];
Thor (atiredmachine)c8efb802012-01-24 13:33:39 -0800573
574 // Has the file expired?
575 if ($_SERVER['REQUEST_TIME'] >= $expire && is_really_writable($cache_path))
Derek Jonesd99e6032010-03-19 19:57:33 -0500576 {
Thor (atiredmachine)c8efb802012-01-24 13:33:39 -0800577 // If so we'll delete it.
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200578 @unlink($filepath);
579 log_message('debug', 'Cache file has expired. File deleted.');
580 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000581 }
Thor (atiredmachine)c8efb802012-01-24 13:33:39 -0800582 else
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300583 {
Thor (atiredmachine)c8efb802012-01-24 13:33:39 -0800584 // Or else send the HTTP cache control headers.
Thor (atiredmachine)5528c0e2012-01-25 01:02:28 -0800585 $this->set_cache_header($last_modified, $expire);
Thor (atiredmachine)c8efb802012-01-24 13:33:39 -0800586 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000587
588 // Display the cache
vlakoff1288fe32012-07-23 16:22:06 +0200589 $this->_display(substr($cache, strlen($match[0])));
Andrey Andreev1f5fbb62012-01-07 20:53:29 +0200590 log_message('debug', 'Cache file is current. Sending it to browser.');
Derek Allard2067d1a2008-11-13 22:59:24 +0000591 return TRUE;
592 }
593
Thor (atiredmachine)c8efb802012-01-24 13:33:39 -0800594 // --------------------------------------------------------------------
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300595
Thor (atiredmachine)c8efb802012-01-24 13:33:39 -0800596 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300597 * Set Cache Header
598 *
Thor (atiredmachine)c8efb802012-01-24 13:33:39 -0800599 * Set the HTTP headers to match the server-side file cache settings
600 * in order to reduce bandwidth.
601 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300602 * @param int $last_modified Timestamp of when the page was last modified
603 * @param int $expiration Timestamp of when should the requested page expire from cache
Thor (atiredmachine)c8efb802012-01-24 13:33:39 -0800604 * @return void
605 */
Thor (atiredmachine)5528c0e2012-01-25 01:02:28 -0800606 public function set_cache_header($last_modified, $expiration)
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300607 {
608 $max_age = $expiration - $_SERVER['REQUEST_TIME'];
Thor (atiredmachine)c8efb802012-01-24 13:33:39 -0800609
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300610 if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $last_modified <= strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']))
Thor (atiredmachine)c8efb802012-01-24 13:33:39 -0800611 {
612 $this->set_status_header(304);
613 exit;
614 }
615 else
616 {
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300617 header('Pragma: public');
Thor (atiredmachine)c8efb802012-01-24 13:33:39 -0800618 header('Cache-Control: max-age=' . $max_age . ', public');
619 header('Expires: '.gmdate('D, d M Y H:i:s', $expiration).' GMT');
620 header('Last-modified: '.gmdate('D, d M Y H:i:s', $last_modified).' GMT');
621 }
622 }
623
Thor (atiredmachine)63678a22012-01-24 16:56:01 -0800624 // --------------------------------------------------------------------
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300625
Thor (atiredmachine)63678a22012-01-24 16:56:01 -0800626 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300627 * Minify
Thor (atiredmachine)63678a22012-01-24 16:56:01 -0800628 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300629 * Reduce excessive size of HTML/CSS/JavaScript content.
630 *
631 * @param string $output Output to minify
632 * @param string $type Output content MIME type
633 * @return string Minified output
Thor (atiredmachine)63678a22012-01-24 16:56:01 -0800634 */
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300635 public function minify($output, $type = 'text/html')
Thor (atiredmachine)63678a22012-01-24 16:56:01 -0800636 {
637 switch ($type)
638 {
Thor (atiredmachine)1d0661a2012-01-24 21:39:16 -0800639 case 'text/html':
Thor (atiredmachine)f59ec6f2012-01-24 22:19:14 -0800640
641 $size_before = strlen($output);
642
Phil Sturgeon7a744a82012-06-23 17:21:00 +0100643 if ($size_before === 0)
644 {
645 return '';
646 }
647
Thor (atiredmachine)5c078ce2012-01-26 17:18:35 -0800648 // Find all the <pre>,<code>,<textarea>, and <javascript> tags
649 // We'll want to return them to this unprocessed state later.
Thor (atiredmachine)5528c0e2012-01-25 01:02:28 -0800650 preg_match_all('{<pre.+</pre>}msU', $output, $pres_clean);
651 preg_match_all('{<code.+</code>}msU', $output, $codes_clean);
652 preg_match_all('{<textarea.+</textarea>}msU', $output, $textareas_clean);
Thor (atiredmachine)5c078ce2012-01-26 17:18:35 -0800653 preg_match_all('{<script.+</script>}msU', $output, $javascript_clean);
Thor (atiredmachine)79db4cd2012-01-24 20:44:51 -0800654
Thor (atiredmachine)d68c8192012-01-24 20:56:21 -0800655 // Minify the CSS in all the <style> tags.
Thor (atiredmachine)5528c0e2012-01-25 01:02:28 -0800656 preg_match_all('{<style.+</style>}msU', $output, $style_clean);
Thor (atiredmachine)79db4cd2012-01-24 20:44:51 -0800657 foreach ($style_clean[0] as $s)
658 {
Thor1b8d0ef2012-01-28 01:48:04 -0800659 $output = str_replace($s, $this->minify($s, 'text/css'), $output);
Thor (atiredmachine)79db4cd2012-01-24 20:44:51 -0800660 }
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300661
Thor (atiredmachine)5c078ce2012-01-26 17:18:35 -0800662 // Minify the javascript in <script> tags.
663 foreach ($javascript_clean[0] as $s)
664 {
Thor1b8d0ef2012-01-28 01:48:04 -0800665 $javascript_mini[] = $this->minify($s, 'text/javascript');
Thor (atiredmachine)5c078ce2012-01-26 17:18:35 -0800666 }
Thor (atiredmachine)79db4cd2012-01-24 20:44:51 -0800667
Thor (atiredmachine)a2ae6e12012-01-24 20:57:48 -0800668 // Replace multiple spaces with a single space.
Thor1b8d0ef2012-01-28 01:48:04 -0800669 $output = preg_replace('!\s{2,}!', ' ', $output);
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300670
Thor (atiredmachine)5de11752012-01-24 22:08:36 -0800671 // Remove comments (non-MSIE conditionals)
Thor (atiredmachine)5528c0e2012-01-25 01:02:28 -0800672 $output = preg_replace('{\s*<!--[^\[].*-->\s*}msU', '', $output);
Thor (atiredmachine)5de11752012-01-24 22:08:36 -0800673
Thor (atiredmachine)a2ae6e12012-01-24 20:57:48 -0800674 // Remove spaces around block-level elements.
Phil Sturgeon3b6af432012-06-21 09:21:17 -0500675 $output = preg_replace('/\s*(<\/?(html|head|title|meta|script|link|style|body|h[1-6]|div|p|br)[^>]*>)\s*/is', '$1', $output);
Thor (atiredmachine)79db4cd2012-01-24 20:44:51 -0800676
Thor (atiredmachine)d68c8192012-01-24 20:56:21 -0800677 // Replace mangled <pre> etc. tags with unprocessed ones.
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300678
Thor (atiredmachine)5c078ce2012-01-26 17:18:35 -0800679 if ( ! empty($pres_clean))
680 {
681 preg_match_all('{<pre.+</pre>}msU', $output, $pres_messed);
682 $output = str_replace($pres_messed[0], $pres_clean[0], $output);
683 }
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300684
Thor (atiredmachine)5c078ce2012-01-26 17:18:35 -0800685 if ( ! empty($codes_clean))
686 {
687 preg_match_all('{<code.+</code>}msU', $output, $codes_messed);
688 $output = str_replace($codes_messed[0], $codes_clean[0], $output);
689 }
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300690
Thor (atiredmachine)5c078ce2012-01-26 17:18:35 -0800691 if ( ! empty($codes_clean))
692 {
693 preg_match_all('{<textarea.+</textarea>}msU', $output, $textareas_messed);
694 $output = str_replace($textareas_messed[0], $textareas_clean[0], $output);
695 }
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300696
Thor (atiredmachine)5c078ce2012-01-26 17:18:35 -0800697 if (isset($javascript_mini))
698 {
699 preg_match_all('{<script.+</script>}msU', $output, $javascript_messed);
700 $output = str_replace($javascript_messed[0], $javascript_mini, $output);
701 }
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300702
Thor (atiredmachine)5c078ce2012-01-26 17:18:35 -0800703 $size_removed = $size_before - strlen($output);
704 $savings_percent = round(($size_removed / $size_before * 100));
705
706 log_message('debug', 'Minifier shaved '.($size_removed / 1000).'KB ('.$savings_percent.'%) off final HTML output.');
Thor (atiredmachine)63678a22012-01-24 16:56:01 -0800707
Thor (atiredmachine)63678a22012-01-24 16:56:01 -0800708 break;
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300709
Thor (atiredmachine)1d0661a2012-01-24 21:39:16 -0800710 case 'text/css':
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300711
Thor (atiredmachine)5c078ce2012-01-26 17:18:35 -0800712 //Remove CSS comments
713 $output = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $output);
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300714
Thor (atiredmachine)5c078ce2012-01-26 17:18:35 -0800715 // Remove spaces around curly brackets, colons,
716 // semi-colons, parenthesis, commas
717 $output = preg_replace('!\s*(:|;|,|}|{|\(|\))\s*!', '$1', $output);
718
719 break;
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300720
Thor (atiredmachine)5c078ce2012-01-26 17:18:35 -0800721 case 'text/javascript':
722
Thor1b8d0ef2012-01-28 01:48:04 -0800723 // Currently leaves JavaScript untouched.
Thor (atiredmachine)79db4cd2012-01-24 20:44:51 -0800724 break;
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300725
726 default: break;
Thor (atiredmachine)63678a22012-01-24 16:56:01 -0800727 }
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300728
Thor (atiredmachine)63678a22012-01-24 16:56:01 -0800729 return $output;
730 }
731
Derek Allard2067d1a2008-11-13 22:59:24 +0000732}
Derek Allard2067d1a2008-11-13 22:59:24 +0000733
734/* End of file Output.php */
Andrey Andreev0140ddd2012-06-16 01:12:56 +0300735/* Location: ./system/core/Output.php */