/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk

« back to all changes in this revision

Viewing changes to codeigniter/system/core/Output.php

  • Committer: galaxyAbstractor
  • Date: 2013-04-10 15:58:59 UTC
  • mfrom: (20.1.1 lenasys)
  • mto: This revision was merged to the branch mainline in revision 23.
  • Revision ID: galaxyabstractor@gmail.com-20130410155859-cih60kaz5es8savt
CodeIgniter implementation of basic CMS system

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
2
/**
 
3
 * CodeIgniter
 
4
 *
 
5
 * An open source application development framework for PHP 5.1.6 or newer
 
6
 *
 
7
 * @package             CodeIgniter
 
8
 * @author              ExpressionEngine Dev Team
 
9
 * @copyright   Copyright (c) 2008 - 2011, 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
        /**
 
32
         * Current output string
 
33
         *
 
34
         * @var string
 
35
         * @access      protected
 
36
         */
 
37
        protected $final_output;
 
38
        /**
 
39
         * Cache expiration time
 
40
         *
 
41
         * @var int
 
42
         * @access      protected
 
43
         */
 
44
        protected $cache_expiration     = 0;
 
45
        /**
 
46
         * List of server headers
 
47
         *
 
48
         * @var array
 
49
         * @access      protected
 
50
         */
 
51
        protected $headers                      = array();
 
52
        /**
 
53
         * List of mime types
 
54
         *
 
55
         * @var array
 
56
         * @access      protected
 
57
         */
 
58
        protected $mime_types           = array();
 
59
        /**
 
60
         * Determines wether profiler is enabled
 
61
         *
 
62
         * @var book
 
63
         * @access      protected
 
64
         */
 
65
        protected $enable_profiler      = FALSE;
 
66
        /**
 
67
         * Determines if output compression is enabled
 
68
         *
 
69
         * @var bool
 
70
         * @access      protected
 
71
         */
 
72
        protected $_zlib_oc                     = FALSE;
 
73
        /**
 
74
         * List of profiler sections
 
75
         *
 
76
         * @var array
 
77
         * @access      protected
 
78
         */
 
79
        protected $_profiler_sections = array();
 
80
        /**
 
81
         * Whether or not to parse variables like {elapsed_time} and {memory_usage}
 
82
         *
 
83
         * @var bool
 
84
         * @access      protected
 
85
         */
 
86
        protected $parse_exec_vars      = TRUE;
 
87
 
 
88
        /**
 
89
         * Constructor
 
90
         *
 
91
         */
 
92
        function __construct()
 
93
        {
 
94
                $this->_zlib_oc = @ini_get('zlib.output_compression');
 
95
 
 
96
                // Get mime types for later
 
97
                if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
 
98
                {
 
99
                    include APPPATH.'config/'.ENVIRONMENT.'/mimes.php';
 
100
                }
 
101
                else
 
102
                {
 
103
                        include APPPATH.'config/mimes.php';
 
104
                }
 
105
 
 
106
 
 
107
                $this->mime_types = $mimes;
 
108
 
 
109
                log_message('debug', "Output Class Initialized");
 
110
        }
 
111
 
 
112
        // --------------------------------------------------------------------
 
113
 
 
114
        /**
 
115
         * Get Output
 
116
         *
 
117
         * Returns the current output string
 
118
         *
 
119
         * @access      public
 
120
         * @return      string
 
121
         */
 
122
        function get_output()
 
123
        {
 
124
                return $this->final_output;
 
125
        }
 
126
 
 
127
        // --------------------------------------------------------------------
 
128
 
 
129
        /**
 
130
         * Set Output
 
131
         *
 
132
         * Sets the output string
 
133
         *
 
134
         * @access      public
 
135
         * @param       string
 
136
         * @return      void
 
137
         */
 
138
        function set_output($output)
 
139
        {
 
140
                $this->final_output = $output;
 
141
 
 
142
                return $this;
 
143
        }
 
144
 
 
145
        // --------------------------------------------------------------------
 
146
 
 
147
        /**
 
148
         * Append Output
 
149
         *
 
150
         * Appends data onto the output string
 
151
         *
 
152
         * @access      public
 
153
         * @param       string
 
154
         * @return      void
 
155
         */
 
156
        function append_output($output)
 
157
        {
 
158
                if ($this->final_output == '')
 
159
                {
 
160
                        $this->final_output = $output;
 
161
                }
 
162
                else
 
163
                {
 
164
                        $this->final_output .= $output;
 
165
                }
 
166
 
 
167
                return $this;
 
168
        }
 
169
 
 
170
        // --------------------------------------------------------------------
 
171
 
 
172
        /**
 
173
         * Set Header
 
174
         *
 
175
         * Lets you set a server header which will be outputted with the final display.
 
176
         *
 
177
         * Note:  If a file is cached, headers will not be sent.  We need to figure out
 
178
         * how to permit header data to be saved with the cache data...
 
179
         *
 
180
         * @access      public
 
181
         * @param       string
 
182
         * @param       bool
 
183
         * @return      void
 
184
         */
 
185
        function set_header($header, $replace = TRUE)
 
186
        {
 
187
                // If zlib.output_compression is enabled it will compress the output,
 
188
                // but it will not modify the content-length header to compensate for
 
189
                // the reduction, causing the browser to hang waiting for more data.
 
190
                // We'll just skip content-length in those cases.
 
191
 
 
192
                if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) == 0)
 
193
                {
 
194
                        return;
 
195
                }
 
196
 
 
197
                $this->headers[] = array($header, $replace);
 
198
 
 
199
                return $this;
 
200
        }
 
201
 
 
202
        // --------------------------------------------------------------------
 
203
 
 
204
        /**
 
205
         * Set Content Type Header
 
206
         *
 
207
         * @access      public
 
208
         * @param       string  extension of the file we're outputting
 
209
         * @return      void
 
210
         */
 
211
        function set_content_type($mime_type)
 
212
        {
 
213
                if (strpos($mime_type, '/') === FALSE)
 
214
                {
 
215
                        $extension = ltrim($mime_type, '.');
 
216
 
 
217
                        // Is this extension supported?
 
218
                        if (isset($this->mime_types[$extension]))
 
219
                        {
 
220
                                $mime_type =& $this->mime_types[$extension];
 
221
 
 
222
                                if (is_array($mime_type))
 
223
                                {
 
224
                                        $mime_type = current($mime_type);
 
225
                                }
 
226
                        }
 
227
                }
 
228
 
 
229
                $header = 'Content-Type: '.$mime_type;
 
230
 
 
231
                $this->headers[] = array($header, TRUE);
 
232
 
 
233
                return $this;
 
234
        }
 
235
 
 
236
        // --------------------------------------------------------------------
 
237
 
 
238
        /**
 
239
         * Set HTTP Status Header
 
240
         * moved to Common procedural functions in 1.7.2
 
241
         *
 
242
         * @access      public
 
243
         * @param       int             the status code
 
244
         * @param       string
 
245
         * @return      void
 
246
         */
 
247
        function set_status_header($code = 200, $text = '')
 
248
        {
 
249
                set_status_header($code, $text);
 
250
 
 
251
                return $this;
 
252
        }
 
253
 
 
254
        // --------------------------------------------------------------------
 
255
 
 
256
        /**
 
257
         * Enable/disable Profiler
 
258
         *
 
259
         * @access      public
 
260
         * @param       bool
 
261
         * @return      void
 
262
         */
 
263
        function enable_profiler($val = TRUE)
 
264
        {
 
265
                $this->enable_profiler = (is_bool($val)) ? $val : TRUE;
 
266
 
 
267
                return $this;
 
268
        }
 
269
 
 
270
        // --------------------------------------------------------------------
 
271
 
 
272
        /**
 
273
         * Set Profiler Sections
 
274
         *
 
275
         * Allows override of default / config settings for Profiler section display
 
276
         *
 
277
         * @access      public
 
278
         * @param       array
 
279
         * @return      void
 
280
         */
 
281
        function set_profiler_sections($sections)
 
282
        {
 
283
                foreach ($sections as $section => $enable)
 
284
                {
 
285
                        $this->_profiler_sections[$section] = ($enable !== FALSE) ? TRUE : FALSE;
 
286
                }
 
287
 
 
288
                return $this;
 
289
        }
 
290
 
 
291
        // --------------------------------------------------------------------
 
292
 
 
293
        /**
 
294
         * Set Cache
 
295
         *
 
296
         * @access      public
 
297
         * @param       integer
 
298
         * @return      void
 
299
         */
 
300
        function cache($time)
 
301
        {
 
302
                $this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;
 
303
 
 
304
                return $this;
 
305
        }
 
306
 
 
307
        // --------------------------------------------------------------------
 
308
 
 
309
        /**
 
310
         * Display Output
 
311
         *
 
312
         * All "view" data is automatically put into this variable by the controller class:
 
313
         *
 
314
         * $this->final_output
 
315
         *
 
316
         * This function sends the finalized output data to the browser along
 
317
         * with any server headers and profile data.  It also stops the
 
318
         * benchmark timer so the page rendering speed and memory usage can be shown.
 
319
         *
 
320
         * @access      public
 
321
         * @param       string
 
322
         * @return      mixed
 
323
         */
 
324
        function _display($output = '')
 
325
        {
 
326
                // Note:  We use globals because we can't use $CI =& get_instance()
 
327
                // since this function is sometimes called by the caching mechanism,
 
328
                // which happens before the CI super object is available.
 
329
                global $BM, $CFG;
 
330
 
 
331
                // Grab the super object if we can.
 
332
                if (class_exists('CI_Controller'))
 
333
                {
 
334
                        $CI =& get_instance();
 
335
                }
 
336
 
 
337
                // --------------------------------------------------------------------
 
338
 
 
339
                // Set the output data
 
340
                if ($output == '')
 
341
                {
 
342
                        $output =& $this->final_output;
 
343
                }
 
344
 
 
345
                // --------------------------------------------------------------------
 
346
 
 
347
                // Do we need to write a cache file?  Only if the controller does not have its
 
348
                // own _output() method and we are not dealing with a cache file, which we
 
349
                // can determine by the existence of the $CI object above
 
350
                if ($this->cache_expiration > 0 && isset($CI) && ! method_exists($CI, '_output'))
 
351
                {
 
352
                        $this->_write_cache($output);
 
353
                }
 
354
 
 
355
                // --------------------------------------------------------------------
 
356
 
 
357
                // Parse out the elapsed time and memory usage,
 
358
                // then swap the pseudo-variables with the data
 
359
 
 
360
                $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');
 
361
 
 
362
                if ($this->parse_exec_vars === TRUE)
 
363
                {
 
364
                        $memory  = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
 
365
 
 
366
                        $output = str_replace('{elapsed_time}', $elapsed, $output);
 
367
                        $output = str_replace('{memory_usage}', $memory, $output);
 
368
                }
 
369
 
 
370
                // --------------------------------------------------------------------
 
371
 
 
372
                // Is compression requested?
 
373
                if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc == FALSE)
 
374
                {
 
375
                        if (extension_loaded('zlib'))
 
376
                        {
 
377
                                if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
 
378
                                {
 
379
                                        ob_start('ob_gzhandler');
 
380
                                }
 
381
                        }
 
382
                }
 
383
 
 
384
                // --------------------------------------------------------------------
 
385
 
 
386
                // Are there any server headers to send?
 
387
                if (count($this->headers) > 0)
 
388
                {
 
389
                        foreach ($this->headers as $header)
 
390
                        {
 
391
                                @header($header[0], $header[1]);
 
392
                        }
 
393
                }
 
394
 
 
395
                // --------------------------------------------------------------------
 
396
 
 
397
                // Does the $CI object exist?
 
398
                // If not we know we are dealing with a cache file so we'll
 
399
                // simply echo out the data and exit.
 
400
                if ( ! isset($CI))
 
401
                {
 
402
                        echo $output;
 
403
                        log_message('debug', "Final output sent to browser");
 
404
                        log_message('debug', "Total execution time: ".$elapsed);
 
405
                        return TRUE;
 
406
                }
 
407
 
 
408
                // --------------------------------------------------------------------
 
409
 
 
410
                // Do we need to generate profile data?
 
411
                // If so, load the Profile class and run it.
 
412
                if ($this->enable_profiler == TRUE)
 
413
                {
 
414
                        $CI->load->library('profiler');
 
415
 
 
416
                        if ( ! empty($this->_profiler_sections))
 
417
                        {
 
418
                                $CI->profiler->set_sections($this->_profiler_sections);
 
419
                        }
 
420
 
 
421
                        // If the output data contains closing </body> and </html> tags
 
422
                        // we will remove them and add them back after we insert the profile data
 
423
                        if (preg_match("|</body>.*?</html>|is", $output))
 
424
                        {
 
425
                                $output  = preg_replace("|</body>.*?</html>|is", '', $output);
 
426
                                $output .= $CI->profiler->run();
 
427
                                $output .= '</body></html>';
 
428
                        }
 
429
                        else
 
430
                        {
 
431
                                $output .= $CI->profiler->run();
 
432
                        }
 
433
                }
 
434
 
 
435
                // --------------------------------------------------------------------
 
436
 
 
437
                // Does the controller contain a function named _output()?
 
438
                // If so send the output there.  Otherwise, echo it.
 
439
                if (method_exists($CI, '_output'))
 
440
                {
 
441
                        $CI->_output($output);
 
442
                }
 
443
                else
 
444
                {
 
445
                        echo $output;  // Send it to the browser!
 
446
                }
 
447
 
 
448
                log_message('debug', "Final output sent to browser");
 
449
                log_message('debug', "Total execution time: ".$elapsed);
 
450
        }
 
451
 
 
452
        // --------------------------------------------------------------------
 
453
 
 
454
        /**
 
455
         * Write a Cache File
 
456
         *
 
457
         * @access      public
 
458
         * @param       string
 
459
         * @return      void
 
460
         */
 
461
        function _write_cache($output)
 
462
        {
 
463
                $CI =& get_instance();
 
464
                $path = $CI->config->item('cache_path');
 
465
 
 
466
                $cache_path = ($path == '') ? APPPATH.'cache/' : $path;
 
467
 
 
468
                if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
 
469
                {
 
470
                        log_message('error', "Unable to write cache file: ".$cache_path);
 
471
                        return;
 
472
                }
 
473
 
 
474
                $uri =  $CI->config->item('base_url').
 
475
                                $CI->config->item('index_page').
 
476
                                $CI->uri->uri_string();
 
477
 
 
478
                $cache_path .= md5($uri);
 
479
 
 
480
                if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE))
 
481
                {
 
482
                        log_message('error', "Unable to write cache file: ".$cache_path);
 
483
                        return;
 
484
                }
 
485
 
 
486
                $expire = time() + ($this->cache_expiration * 60);
 
487
 
 
488
                if (flock($fp, LOCK_EX))
 
489
                {
 
490
                        fwrite($fp, $expire.'TS--->'.$output);
 
491
                        flock($fp, LOCK_UN);
 
492
                }
 
493
                else
 
494
                {
 
495
                        log_message('error', "Unable to secure a file lock for file at: ".$cache_path);
 
496
                        return;
 
497
                }
 
498
                fclose($fp);
 
499
                @chmod($cache_path, FILE_WRITE_MODE);
 
500
 
 
501
                log_message('debug', "Cache file written: ".$cache_path);
 
502
        }
 
503
 
 
504
        // --------------------------------------------------------------------
 
505
 
 
506
        /**
 
507
         * Update/serve a cached file
 
508
         *
 
509
         * @access      public
 
510
         * @param       object  config class
 
511
         * @param       object  uri class
 
512
         * @return      void
 
513
         */
 
514
        function _display_cache(&$CFG, &$URI)
 
515
        {
 
516
                $cache_path = ($CFG->item('cache_path') == '') ? APPPATH.'cache/' : $CFG->item('cache_path');
 
517
 
 
518
                // Build the file path.  The file name is an MD5 hash of the full URI
 
519
                $uri =  $CFG->item('base_url').
 
520
                                $CFG->item('index_page').
 
521
                                $URI->uri_string;
 
522
 
 
523
                $filepath = $cache_path.md5($uri);
 
524
 
 
525
                if ( ! @file_exists($filepath))
 
526
                {
 
527
                        return FALSE;
 
528
                }
 
529
 
 
530
                if ( ! $fp = @fopen($filepath, FOPEN_READ))
 
531
                {
 
532
                        return FALSE;
 
533
                }
 
534
 
 
535
                flock($fp, LOCK_SH);
 
536
 
 
537
                $cache = '';
 
538
                if (filesize($filepath) > 0)
 
539
                {
 
540
                        $cache = fread($fp, filesize($filepath));
 
541
                }
 
542
 
 
543
                flock($fp, LOCK_UN);
 
544
                fclose($fp);
 
545
 
 
546
                // Strip out the embedded timestamp
 
547
                if ( ! preg_match("/(\d+TS--->)/", $cache, $match))
 
548
                {
 
549
                        return FALSE;
 
550
                }
 
551
 
 
552
                // Has the file expired? If so we'll delete it.
 
553
                if (time() >= trim(str_replace('TS--->', '', $match['1'])))
 
554
                {
 
555
                        if (is_really_writable($cache_path))
 
556
                        {
 
557
                                @unlink($filepath);
 
558
                                log_message('debug', "Cache file has expired. File deleted");
 
559
                                return FALSE;
 
560
                        }
 
561
                }
 
562
 
 
563
                // Display the cache
 
564
                $this->_display(str_replace($match['0'], '', $cache));
 
565
                log_message('debug', "Cache file is current. Sending it to browser.");
 
566
                return TRUE;
 
567
        }
 
568
 
 
569
 
 
570
}
 
571
// END Output Class
 
572
 
 
573
/* End of file Output.php */
 
574
/* Location: ./system/core/Output.php */
 
 
b'\\ No newline at end of file'