]> git.donarmstrong.com Git - roundcube.git/blob - program/include/rcube_html_page.php
Imported Upstream version 0.3
[roundcube.git] / program / include / rcube_html_page.php
1 <?php
2
3 /*
4  +-----------------------------------------------------------------------+
5  | program/include/rcube_html_page.php                                   |
6  |                                                                       |
7  | This file is part of the RoundCube PHP suite                          |
8  | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
9  | Licensed under the GNU GPL                                            |
10  |                                                                       |
11  | CONTENTS:                                                             |
12  |   Class to build XHTML page output                                    |
13  |                                                                       |
14  +-----------------------------------------------------------------------+
15  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
16  +-----------------------------------------------------------------------+
17
18  $Id:  $
19
20 */
21
22 /**
23  * Class for HTML page creation
24  *
25  * @package HTML
26  */
27 class rcube_html_page
28 {
29     protected $scripts_path = '';
30     protected $script_files = array();
31     protected $scripts = array();
32     protected $charset = RCMAIL_CHARSET;
33
34     protected $script_tag_file = "<script type=\"text/javascript\" src=\"%s\"></script>\n";
35     protected $script_tag  =  "<script type=\"text/javascript\">\n/* <![CDATA[ */\n%s\n/* ]]> */\n</script>";
36     protected $default_template = "<html>\n<head><title></title></head>\n<body></body>\n</html>";
37
38     protected $title = '';
39     protected $header = '';
40     protected $footer = '';
41     protected $body = '';
42
43
44     /** Constructor */
45     public function __construct() {}
46
47     /**
48      * Link an external script file
49      *
50      * @param string File URL
51      * @param string Target position [head|foot]
52      */
53     public function include_script($file, $position='head')
54     {
55         static $sa_files = array();
56         
57         if (!preg_match('|^https?://|i', $file) && $file[0] != '/')
58           $file = $this->scripts_path . $file . (($fs = @filemtime($this->scripts_path . $file)) ? '?s='.$fs : '');
59
60         if (in_array($file, $sa_files)) {
61             return;
62         }
63         if (!is_array($this->script_files[$position])) {
64             $this->script_files[$position] = array();
65         }
66         $this->script_files[$position][] = $file;
67     }
68
69     /**
70      * Add inline javascript code
71      *
72      * @param string JS code snippet
73      * @param string Target position [head|head_top|foot]
74      */
75     public function add_script($script, $position='head')
76     {
77         if (!isset($this->scripts[$position])) {
78             $this->scripts[$position] = "\n".rtrim($script);
79         } else {
80             $this->scripts[$position] .= "\n".rtrim($script);
81         }
82     }
83
84     /**
85      * Add HTML code to the page header
86      */
87     public function add_header($str)
88     {
89         $this->header .= "\n".$str;
90     }
91
92     /**
93      * Add HTML code to the page footer
94      * To be added right befor </body>
95      */
96     public function add_footer($str)
97     {
98         $this->footer .= "\n".$str;
99     }
100
101     /**
102      * Setter for page title
103      */
104     public function set_title($t)
105     {
106         $this->title = $t;
107     }
108
109     /**
110      * Setter for output charset.
111      * To be specified in a meta tag and sent as http-header
112      */
113     public function set_charset($charset)
114     {
115         $this->charset = $charset;
116     }
117
118     /**
119      * Getter for output charset
120      */
121     public function get_charset()
122     {
123         return $this->charset;
124     }
125
126     /**
127      * Reset all saved properties
128      */
129     public function reset()
130     {
131         $this->script_files = array();
132         $this->scripts = array();
133         $this->title = '';
134         $this->header = '';
135         $this->footer = '';
136         $this->body = '';
137     }
138
139     /**
140      * Process template and write to stdOut
141      *
142      * @param string HTML template
143      * @param string Base for absolute paths
144      */
145     public function write($templ='', $base_path='')
146     {
147         $output = empty($templ) ? $this->default_template : trim($templ);
148
149         // set default page title
150         if (empty($this->title)) {
151             $this->title = 'RoundCube Mail';
152         }
153
154         // replace specialchars in content
155         $__page_title = Q($this->title, 'show', FALSE);
156         $__page_header = $__page_body = $__page_footer = '';
157
158         // include meta tag with charset
159         if (!empty($this->charset)) {
160             if (!headers_sent()) {
161                 header('Content-Type: text/html; charset=' . $this->charset);
162             }
163             $__page_header = '<meta http-equiv="content-type"';
164             $__page_header.= ' content="text/html; charset=';
165             $__page_header.= $this->charset . '" />'."\n";
166         }
167
168         // definition of the code to be placed in the document header and footer
169         if (is_array($this->script_files['head'])) {
170             foreach ($this->script_files['head'] as $file) {
171                 $__page_header .= sprintf($this->script_tag_file, $file);
172             }
173         }
174
175         $head_script = $this->scripts['head_top'] . $this->scripts['head'];
176         if (!empty($head_script)) {
177             $__page_header .= sprintf($this->script_tag, $head_script);
178         }
179
180         if (!empty($this->header)) {
181             $__page_header .= $this->header;
182         }
183
184         if (is_array($this->script_files['foot'])) {
185             foreach ($this->script_files['foot'] as $file) {
186                 $__page_footer .= sprintf($this->script_tag_file, $file);
187             }
188         }
189
190         if (!empty($this->scripts['foot'])) {
191             $__page_footer .= sprintf($this->script_tag, $this->scripts['foot']);
192         }
193
194         if (!empty($this->footer)) {
195             $__page_footer .= $this->footer;
196         }
197
198         // find page header
199         if ($hpos = strpos(strtolower($output), '</head>')) {
200             $__page_header .= "\n";
201         }
202         else {
203             if (!is_numeric($hpos)) {
204                 $hpos = strpos(strtolower($output), '<body');
205             }
206             if (!is_numeric($hpos) && ($hpos = strpos(strtolower($output), '<html'))) {
207                 while ($output[$hpos] != '>') {
208                     $hpos++;
209                 }
210                 $hpos++;
211             }
212             $__page_header = "<head>\n<title>$__page_title</title>\n$__page_header\n</head>\n";
213         }
214
215         // add page hader
216         if ($hpos) {
217             $output = substr($output,0,$hpos) . $__page_header . substr($output,$hpos,strlen($output));
218         }
219         else {
220             $output = $__page_header . $output;
221         }
222
223         // find page body
224         if ($bpos = strpos(strtolower($output), '<body')) {
225             while ($output[$bpos] != '>') {
226                 $bpos++;
227             }
228             $bpos++;
229         }
230         else {
231             $bpos = strpos(strtolower($output), '</head>')+7;
232         }
233
234         // add page body
235         if ($bpos && $__page_body) {
236             $output = substr($output,0,$bpos) . "\n$__page_body\n" . substr($output,$bpos,strlen($output));
237         }
238
239         // find and add page footer
240         $output_lc = strtolower($output);
241         if (($fpos = strrpos($output_lc, '</body>')) || ($fpos = strrpos($output_lc, '</html>'))) {
242             $output = substr($output, 0, $fpos) . "$__page_footer\n" . substr($output, $fpos);
243         }
244         else {
245             $output .= "\n".$__page_footer;
246         }
247
248         // reset those global vars
249         $__page_header = $__page_footer = '';
250
251         // correct absolute paths in images and other tags
252         $output = preg_replace('!(src|href|background)=(["\']?)(/[a-z0-9_-]+)!i', "\\1=\\2$base_path\\3", $output);
253         $output = preg_replace_callback('!(src|href)=(["\']?)([a-z0-9/_.-]+.(css|js))(["\'\s>])!i', array($this, 'add_filemtime'), $output);
254         $output = str_replace('$__skin_path', $base_path, $output);
255
256         if ($this->charset != RCMAIL_CHARSET)
257             echo rcube_charset_convert($output, RCMAIL_CHARSET, $this->charset);
258         else
259             echo $output;
260     }
261     
262     /**
263      * Callback function for preg_replace_callback in write()
264      */
265     public function add_filemtime($matches)
266     {
267         return sprintf("%s=%s%s?s=%d%s", $matches[1], $matches[2], $matches[3], @filemtime($matches[3]), $matches[5]);
268     }
269 }
270