source: subversion/trunk/roundcubemail/program/include/rcube_html_page.php @ 2672

Last change on this file since 2672 was 2672, checked in by alec, 4 years ago
  • use RCMAIL_CHARSET instead of hardcoded 'utf-8'
File size: 8.2 KB
Line 
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 */
27class 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
Note: See TracBrowser for help on using the repository browser.