0
|
1 <?php
|
|
2
|
|
3 /**
|
|
4 +-----------------------------------------------------------------------+
|
|
5 | This file is part of the Roundcube PHP suite |
|
|
6 | Copyright (C) 2005-2014 The Roundcube Dev Team |
|
|
7 | |
|
|
8 | Licensed under the GNU General Public License version 3 or |
|
|
9 | any later version with exceptions for skins & plugins. |
|
|
10 | See the README file for a full license statement. |
|
|
11 | |
|
|
12 | CONTENTS: |
|
|
13 | Abstract class for output generation |
|
|
14 +-----------------------------------------------------------------------+
|
|
15 | Author: Thomas Bruederli <roundcube@gmail.com> |
|
|
16 | Author: Aleksander Machniak <alec@alec.pl> |
|
|
17 +-----------------------------------------------------------------------+
|
|
18 */
|
|
19
|
|
20 /**
|
|
21 * Class for output generation
|
|
22 *
|
|
23 * @package Framework
|
|
24 * @subpackage View
|
|
25 */
|
|
26 abstract class rcube_output
|
|
27 {
|
|
28 public $browser;
|
|
29
|
|
30 protected $app;
|
|
31 protected $config;
|
|
32 protected $charset = RCUBE_CHARSET;
|
|
33 protected $env = array();
|
|
34 protected $skins = array();
|
|
35
|
|
36
|
|
37 /**
|
|
38 * Object constructor
|
|
39 */
|
|
40 public function __construct()
|
|
41 {
|
|
42 $this->app = rcube::get_instance();
|
|
43 $this->config = $this->app->config;
|
|
44 $this->browser = new rcube_browser();
|
|
45 }
|
|
46
|
|
47 /**
|
|
48 * Magic getter
|
|
49 */
|
|
50 public function __get($var)
|
|
51 {
|
|
52 // allow read-only access to some members
|
|
53 switch ($var) {
|
|
54 case 'env': return $this->env;
|
|
55 case 'skins': return $this->skins;
|
|
56 case 'charset': return $this->charset;
|
|
57 }
|
|
58
|
|
59 return null;
|
|
60 }
|
|
61
|
|
62 /**
|
|
63 * Setter for output charset.
|
|
64 * To be specified in a meta tag and sent as http-header
|
|
65 *
|
|
66 * @param string $charset Charset name
|
|
67 */
|
|
68 public function set_charset($charset)
|
|
69 {
|
|
70 $this->charset = $charset;
|
|
71 }
|
|
72
|
|
73 /**
|
|
74 * Getter for output charset
|
|
75 *
|
|
76 * @return string Output charset name
|
|
77 */
|
|
78 public function get_charset()
|
|
79 {
|
|
80 return $this->charset;
|
|
81 }
|
|
82
|
|
83 /**
|
|
84 * Set environment variable
|
|
85 *
|
|
86 * @param string $name Property name
|
|
87 * @param mixed $value Property value
|
|
88 */
|
|
89 public function set_env($name, $value)
|
|
90 {
|
|
91 $this->env[$name] = $value;
|
|
92 }
|
|
93
|
|
94 /**
|
|
95 * Environment variable getter.
|
|
96 *
|
|
97 * @param string $name Property name
|
|
98 *
|
|
99 * @return mixed Property value
|
|
100 */
|
|
101 public function get_env($name)
|
|
102 {
|
|
103 return $this->env[$name];
|
|
104 }
|
|
105
|
|
106 /**
|
|
107 * Delete all stored env variables and commands
|
|
108 */
|
|
109 public function reset()
|
|
110 {
|
|
111 $this->env = array();
|
|
112 }
|
|
113
|
|
114 /**
|
|
115 * Invoke display_message command
|
|
116 *
|
|
117 * @param string $message Message to display
|
|
118 * @param string $type Message type [notice|confirm|error]
|
|
119 * @param array $vars Key-value pairs to be replaced in localized text
|
|
120 * @param boolean $override Override last set message
|
|
121 * @param int $timeout Message displaying time in seconds
|
|
122 */
|
|
123 abstract function show_message($message, $type = 'notice', $vars = null, $override = true, $timeout = 0);
|
|
124
|
|
125 /**
|
|
126 * Redirect to a certain url.
|
|
127 *
|
|
128 * @param mixed $p Either a string with the action or url parameters as key-value pairs
|
|
129 * @param int $delay Delay in seconds
|
|
130 */
|
|
131 abstract function redirect($p = array(), $delay = 1);
|
|
132
|
|
133 /**
|
|
134 * Send output to the client.
|
|
135 */
|
|
136 abstract function send();
|
|
137
|
|
138 /**
|
|
139 * Send HTTP headers to prevent caching a page
|
|
140 */
|
|
141 public function nocacheing_headers()
|
|
142 {
|
|
143 if (headers_sent()) {
|
|
144 return;
|
|
145 }
|
|
146
|
|
147 header("Expires: ".gmdate("D, d M Y H:i:s")." GMT");
|
|
148 header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
|
149
|
|
150 // We need to set the following headers to make downloads work using IE in HTTPS mode.
|
|
151 if ($this->browser->ie && rcube_utils::https_check()) {
|
|
152 header('Pragma: private');
|
|
153 header("Cache-Control: private, must-revalidate");
|
|
154 }
|
|
155 else {
|
|
156 header("Cache-Control: private, no-cache, no-store, must-revalidate, post-check=0, pre-check=0");
|
|
157 header("Pragma: no-cache");
|
|
158 }
|
|
159 }
|
|
160
|
|
161 /**
|
|
162 * Send header with expire date 30 days in future
|
|
163 *
|
|
164 * @param int Expiration time in seconds
|
|
165 */
|
|
166 public function future_expire_header($offset = 2600000)
|
|
167 {
|
|
168 if (headers_sent()) {
|
|
169 return;
|
|
170 }
|
|
171
|
|
172 header("Expires: " . gmdate("D, d M Y H:i:s", time()+$offset) . " GMT");
|
|
173 header("Cache-Control: max-age=$offset");
|
|
174 header("Pragma: ");
|
|
175 }
|
|
176
|
|
177 /**
|
|
178 * Send browser compatibility/security/etc. headers
|
|
179 */
|
|
180 public function common_headers()
|
|
181 {
|
|
182 if (headers_sent()) {
|
|
183 return;
|
|
184 }
|
|
185
|
|
186 // Unlock IE compatibility mode
|
|
187 if ($this->browser->ie) {
|
|
188 header('X-UA-Compatible: IE=edge');
|
|
189 }
|
|
190
|
|
191 // Request browser to disable DNS prefetching (CVE-2010-0464)
|
|
192 header("X-DNS-Prefetch-Control: off");
|
|
193
|
|
194 // send CSRF and clickjacking protection headers
|
|
195 if ($xframe = $this->app->config->get('x_frame_options', 'sameorigin')) {
|
|
196 header('X-Frame-Options: ' . $xframe);
|
|
197 }
|
|
198 }
|
|
199
|
|
200 /**
|
|
201 * Show error page and terminate script execution
|
|
202 *
|
|
203 * @param int $code Error code
|
|
204 * @param string $message Error message
|
|
205 */
|
|
206 public function raise_error($code, $message)
|
|
207 {
|
|
208 // STUB: to be overloaded by specific output classes
|
|
209 fputs(STDERR, "Error $code: $message\n");
|
|
210 exit(-1);
|
|
211 }
|
|
212
|
|
213 /**
|
|
214 * Create an edit field for inclusion on a form
|
|
215 *
|
|
216 * @param string $col Field name
|
|
217 * @param string $value Field value
|
|
218 * @param array $attrib HTML element attributes for the field
|
|
219 * @param string $type HTML element type (default 'text')
|
|
220 *
|
|
221 * @return string HTML field definition
|
|
222 */
|
|
223 public static function get_edit_field($col, $value, $attrib, $type = 'text')
|
|
224 {
|
|
225 static $colcounts = array();
|
|
226
|
|
227 $fname = '_'.$col;
|
|
228 $attrib['name'] = $fname . ($attrib['array'] ? '[]' : '');
|
|
229 $attrib['class'] = trim($attrib['class'] . ' ff_' . $col);
|
|
230
|
|
231 if ($type == 'checkbox') {
|
|
232 $attrib['value'] = '1';
|
|
233 $input = new html_checkbox($attrib);
|
|
234 }
|
|
235 else if ($type == 'textarea') {
|
|
236 $attrib['cols'] = $attrib['size'];
|
|
237 $input = new html_textarea($attrib);
|
|
238 }
|
|
239 else if ($type == 'select') {
|
|
240 $input = new html_select($attrib);
|
|
241 $input->add('---', '');
|
|
242 $input->add(array_values($attrib['options']), array_keys($attrib['options']));
|
|
243 }
|
|
244 else if ($type == 'password' || $attrib['type'] == 'password') {
|
|
245 $input = new html_passwordfield($attrib);
|
|
246 }
|
|
247 else {
|
|
248 if ($attrib['type'] != 'text' && $attrib['type'] != 'hidden') {
|
|
249 $attrib['type'] = 'text';
|
|
250 }
|
|
251 $input = new html_inputfield($attrib);
|
|
252 }
|
|
253
|
|
254 // use value from post
|
|
255 if (isset($_POST[$fname])) {
|
|
256 $postvalue = rcube_utils::get_input_value($fname, rcube_utils::INPUT_POST, true);
|
|
257 $value = $attrib['array'] ? $postvalue[intval($colcounts[$col]++)] : $postvalue;
|
|
258 }
|
|
259
|
|
260 $out = $input->show($value);
|
|
261
|
|
262 return $out;
|
|
263 }
|
|
264
|
|
265 /**
|
|
266 * Convert a variable into a javascript object notation
|
|
267 *
|
|
268 * @param mixed $input Input value
|
|
269 * @param boolean $pretty Enable JSON formatting
|
|
270 *
|
|
271 * @return string Serialized JSON string
|
|
272 */
|
|
273 public static function json_serialize($input, $pretty = false)
|
|
274 {
|
|
275 $input = rcube_charset::clean($input);
|
|
276 $options = 0;
|
|
277
|
|
278 if ($pretty) {
|
|
279 $options |= JSON_PRETTY_PRINT;
|
|
280 }
|
|
281
|
|
282 // sometimes even using rcube_charset::clean() the input contains invalid UTF-8 sequences
|
|
283 // that's why we have @ here
|
|
284 return @json_encode($input, $options);
|
|
285 }
|
|
286 }
|