upgrade to codeigniter 1.7.2 for f12
[www-register-wizard.git] / libraries / Output.php
1 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2 /**
3  * CodeIgniter
4  *
5  * An open source application development framework for PHP 4.3.2 or newer
6  *
7  * @package             CodeIgniter
8  * @author              ExpressionEngine Dev Team
9  * @copyright   Copyright (c) 2008 - 2009, EllisLab, Inc.
10  * @license             http://codeigniter.com/user_guide/license.html
11  * @link                http://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              ExpressionEngine Dev Team
27  * @link                http://codeigniter.com/user_guide/libraries/output.html
28  */
29 class CI_Output {
30
31         var $final_output;
32         var $cache_expiration   = 0;
33         var $headers                    = array();
34         var $enable_profiler    = FALSE;
35
36
37         function CI_Output()
38         {
39                 log_message('debug', "Output Class Initialized");
40         }
41         
42         // --------------------------------------------------------------------
43         
44         /**
45          * Get Output
46          *
47          * Returns the current output string
48          *
49          * @access      public
50          * @return      string
51          */     
52         function get_output()
53         {
54                 return $this->final_output;
55         }
56         
57         // --------------------------------------------------------------------
58         
59         /**
60          * Set Output
61          *
62          * Sets the output string
63          *
64          * @access      public
65          * @param       string
66          * @return      void
67          */     
68         function set_output($output)
69         {
70                 $this->final_output = $output;
71         }
72
73         // --------------------------------------------------------------------
74
75         /**
76          * Append Output
77          *
78          * Appends data onto the output string
79          *
80          * @access      public
81          * @param       string
82          * @return      void
83          */     
84         function append_output($output)
85         {
86                 if ($this->final_output == '')
87                 {
88                         $this->final_output = $output;
89                 }
90                 else
91                 {
92                         $this->final_output .= $output;
93                 }
94         }
95
96         // --------------------------------------------------------------------
97
98         /**
99          * Set Header
100          *
101          * Lets you set a server header which will be outputted with the final display.
102          *
103          * Note:  If a file is cached, headers will not be sent.  We need to figure out
104          * how to permit header data to be saved with the cache data...
105          *
106          * @access      public
107          * @param       string
108          * @return      void
109          */     
110         function set_header($header, $replace = TRUE)
111         {
112                 $this->headers[] = array($header, $replace);
113         }
114
115         // --------------------------------------------------------------------
116         
117         /**
118          * Set HTTP Status Header
119          * moved to Common procedural functions in 1.7.2
120          * 
121          * @access      public
122          * @param       int     the status code
123          * @param       string  
124          * @return      void
125          */     
126         function set_status_header($code = '200', $text = '')
127         {
128                 set_status_header($code, $text);
129         }
130         
131         // --------------------------------------------------------------------
132         
133         /**
134          * Enable/disable Profiler
135          *
136          * @access      public
137          * @param       bool
138          * @return      void
139          */     
140         function enable_profiler($val = TRUE)
141         {
142                 $this->enable_profiler = (is_bool($val)) ? $val : TRUE;
143         }
144         
145         // --------------------------------------------------------------------
146         
147         /**
148          * Set Cache
149          *
150          * @access      public
151          * @param       integer
152          * @return      void
153          */     
154         function cache($time)
155         {
156                 $this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;
157         }
158         
159         // --------------------------------------------------------------------
160         
161         /**
162          * Display Output
163          *
164          * All "view" data is automatically put into this variable by the controller class:
165          *
166          * $this->final_output
167          *
168          * This function sends the finalized output data to the browser along
169          * with any server headers and profile data.  It also stops the
170          * benchmark timer so the page rendering speed and memory usage can be shown.
171          *
172          * @access      public
173          * @return      mixed
174          */             
175         function _display($output = '')
176         {       
177                 // Note:  We use globals because we can't use $CI =& get_instance()
178                 // since this function is sometimes called by the caching mechanism,
179                 // which happens before the CI super object is available.
180                 global $BM, $CFG;
181                 
182                 // --------------------------------------------------------------------
183                 
184                 // Set the output data
185                 if ($output == '')
186                 {
187                         $output =& $this->final_output;
188                 }
189                 
190                 // --------------------------------------------------------------------
191                 
192                 // Do we need to write a cache file?
193                 if ($this->cache_expiration > 0)
194                 {
195                         $this->_write_cache($output);
196                 }
197                 
198                 // --------------------------------------------------------------------
199
200                 // Parse out the elapsed time and memory usage,
201                 // then swap the pseudo-variables with the data
202
203                 $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');         
204                 $output = str_replace('{elapsed_time}', $elapsed, $output);
205                 
206                 $memory  = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
207                 $output = str_replace('{memory_usage}', $memory, $output);              
208
209                 // --------------------------------------------------------------------
210                 
211                 // Is compression requested?
212                 if ($CFG->item('compress_output') === TRUE)
213                 {
214                         if (extension_loaded('zlib'))
215                         {
216                                 if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
217                                 {
218                                         ob_start('ob_gzhandler');
219                                 }
220                         }
221                 }
222
223                 // --------------------------------------------------------------------
224                 
225                 // Are there any server headers to send?
226                 if (count($this->headers) > 0)
227                 {
228                         foreach ($this->headers as $header)
229                         {
230                                 @header($header[0], $header[1]);
231                         }
232                 }               
233
234                 // --------------------------------------------------------------------
235                 
236                 // Does the get_instance() function exist?
237                 // If not we know we are dealing with a cache file so we'll
238                 // simply echo out the data and exit.
239                 if ( ! function_exists('get_instance'))
240                 {
241                         echo $output;
242                         log_message('debug', "Final output sent to browser");
243                         log_message('debug', "Total execution time: ".$elapsed);
244                         return TRUE;
245                 }
246         
247                 // --------------------------------------------------------------------
248
249                 // Grab the super object.  We'll need it in a moment...
250                 $CI =& get_instance();
251                 
252                 // Do we need to generate profile data?
253                 // If so, load the Profile class and run it.
254                 if ($this->enable_profiler == TRUE)
255                 {
256                         $CI->load->library('profiler');                         
257                                                                                 
258                         // If the output data contains closing </body> and </html> tags
259                         // we will remove them and add them back after we insert the profile data
260                         if (preg_match("|</body>.*?</html>|is", $output))
261                         {
262                                 $output  = preg_replace("|</body>.*?</html>|is", '', $output);
263                                 $output .= $CI->profiler->run();
264                                 $output .= '</body></html>';
265                         }
266                         else
267                         {
268                                 $output .= $CI->profiler->run();
269                         }
270                 }
271                 
272                 // --------------------------------------------------------------------
273
274                 // Does the controller contain a function named _output()?
275                 // If so send the output there.  Otherwise, echo it.
276                 if (method_exists($CI, '_output'))
277                 {
278                         $CI->_output($output);
279                 }
280                 else
281                 {
282                         echo $output;  // Send it to the browser!
283                 }
284                 
285                 log_message('debug', "Final output sent to browser");
286                 log_message('debug', "Total execution time: ".$elapsed);                
287         }
288         
289         // --------------------------------------------------------------------
290         
291         /**
292          * Write a Cache File
293          *
294          * @access      public
295          * @return      void
296          */     
297         function _write_cache($output)
298         {
299                 $CI =& get_instance();  
300                 $path = $CI->config->item('cache_path');
301         
302                 $cache_path = ($path == '') ? BASEPATH.'cache/' : $path;
303                 
304                 if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
305                 {
306                         return;
307                 }
308                 
309                 $uri =  $CI->config->item('base_url').
310                                 $CI->config->item('index_page').
311                                 $CI->uri->uri_string();
312                 
313                 $cache_path .= md5($uri);
314
315                 if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE))
316                 {
317                         log_message('error', "Unable to write cache file: ".$cache_path);
318                         return;
319                 }
320                 
321                 $expire = time() + ($this->cache_expiration * 60);
322                 
323                 if (flock($fp, LOCK_EX))
324                 {
325                         fwrite($fp, $expire.'TS--->'.$output);
326                         flock($fp, LOCK_UN);
327                 }
328                 else
329                 {
330                         log_message('error', "Unable to secure a file lock for file at: ".$cache_path);
331                         return;
332                 }
333                 fclose($fp);
334                 @chmod($cache_path, DIR_WRITE_MODE);
335
336                 log_message('debug', "Cache file written: ".$cache_path);
337         }
338
339         // --------------------------------------------------------------------
340         
341         /**
342          * Update/serve a cached file
343          *
344          * @access      public
345          * @return      void
346          */     
347         function _display_cache(&$CFG, &$URI)
348         {
349                 $cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path');
350                         
351                 if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
352                 {
353                         return FALSE;
354                 }
355                 
356                 // Build the file path.  The file name is an MD5 hash of the full URI
357                 $uri =  $CFG->item('base_url').
358                                 $CFG->item('index_page').
359                                 $URI->uri_string;
360                                 
361                 $filepath = $cache_path.md5($uri);
362                 
363                 if ( ! @file_exists($filepath))
364                 {
365                         return FALSE;
366                 }
367         
368                 if ( ! $fp = @fopen($filepath, FOPEN_READ))
369                 {
370                         return FALSE;
371                 }
372                         
373                 flock($fp, LOCK_SH);
374                 
375                 $cache = '';
376                 if (filesize($filepath) > 0)
377                 {
378                         $cache = fread($fp, filesize($filepath));
379                 }
380         
381                 flock($fp, LOCK_UN);
382                 fclose($fp);
383                                         
384                 // Strip out the embedded timestamp             
385                 if ( ! preg_match("/(\d+TS--->)/", $cache, $match))
386                 {
387                         return FALSE;
388                 }
389                 
390                 // Has the file expired? If so we'll delete it.
391                 if (time() >= trim(str_replace('TS--->', '', $match['1'])))
392                 {               
393                         @unlink($filepath);
394                         log_message('debug', "Cache file has expired. File deleted");
395                         return FALSE;
396                 }
397
398                 // Display the cache
399                 $this->_display(str_replace($match['0'], '', $cache));
400                 log_message('debug', "Cache file is current. Sending it to browser.");          
401                 return TRUE;
402         }
403
404
405 }
406 // END Output Class
407
408 /* End of file Output.php */
409 /* Location: ./system/libraries/Output.php */