source: subversion/trunk/roundcubemail/program/include/rcube_json_output.php @ 5037

Last change on this file since 5037 was 5037, checked in by alec, 23 months ago
  • Fix XSS vulnerability in UI messages (#1488030)
  • Property svn:keywords set to Id
File size: 7.3 KB
Line 
1<?php
2
3/*
4 +-----------------------------------------------------------------------+
5 | program/include/rcube_json_output.php                                 |
6 |                                                                       |
7 | This file is part of the Roundcube Webmail client                     |
8 | Copyright (C) 2008-2010, The Roundcube Dev Team                       |
9 | Licensed under the GNU GPL                                            |
10 |                                                                       |
11 | PURPOSE:                                                              |
12 |   Class to handle HTML page output using a skin template.             |
13 |   Extends rcube_html_page class from rcube_shared.inc                 |
14 |                                                                       |
15 +-----------------------------------------------------------------------+
16 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
17 +-----------------------------------------------------------------------+
18
19 $Id$
20
21*/
22
23
24/**
25 * View class to produce JSON responses
26 *
27 * @package View
28 */
29class rcube_json_output
30{
31    /**
32     * Stores configuration object.
33     *
34     * @var rcube_config
35     */
36    private $config;
37    private $charset = RCMAIL_CHARSET;
38    private $texts = array();
39    private $commands = array();
40    private $callbacks = array();
41    private $message = null;
42
43    public $browser;
44    public $env = array();
45    public $type = 'js';
46    public $ajax_call = true;
47
48
49    /**
50     * Constructor
51     */
52    public function __construct($task=null)
53    {
54        $this->config  = rcmail::get_instance()->config;
55        $this->browser = new rcube_browser();
56    }
57
58
59    /**
60     * Set environment variable
61     *
62     * @param string $name Property name
63     * @param mixed $value Property value
64     */
65    public function set_env($name, $value)
66    {
67        $this->env[$name] = $value;
68    }
69
70
71    /**
72     * Issue command to set page title
73     *
74     * @param string $title New page title
75     */
76    public function set_pagetitle($title)
77    {
78        if ($this->config->get('devel_mode') && !empty($_SESSION['username']))
79            $name = $_SESSION['username'];
80        else
81            $name = $this->config->get('product_name');
82
83        $this->command('set_pagetitle', empty($name) ? $title : $name.' :: '.$title);
84    }
85
86
87    /**
88     * @ignore
89     */
90    function set_charset($charset)
91    {
92        // ignore: $this->charset = $charset;
93    }
94
95
96    /**
97     * Get charset for output
98     *
99     * @return string Output charset
100     */
101    function get_charset()
102    {
103        return $this->charset;
104    }
105
106
107    /**
108     * Register a template object handler
109     *
110     * @param  string $obj Object name
111     * @param  string $func Function name to call
112     * @return void
113     */
114    public function add_handler($obj, $func)
115    {
116        // ignore
117    }
118
119
120    /**
121     * Register a list of template object handlers
122     *
123     * @param  array $arr Hash array with object=>handler pairs
124     * @return void
125     */
126    public function add_handlers($arr)
127    {
128        // ignore
129    }
130
131
132    /**
133     * Call a client method
134     *
135     * @param string Method to call
136     * @param ... Additional arguments
137     */
138    public function command()
139    {
140        $cmd = func_get_args();
141
142        if (strpos($cmd[0], 'plugin.') === 0)
143          $this->callbacks[] = $cmd;
144        else
145          $this->commands[] = $cmd;
146    }
147
148
149    /**
150     * Add a localized label to the client environment
151     */
152    public function add_label()
153    {
154        $args = func_get_args();
155        if (count($args) == 1 && is_array($args[0]))
156            $args = $args[0];
157
158        foreach ($args as $name) {
159            $this->texts[$name] = rcube_label($name);
160        }
161    }
162
163
164    /**
165     * Invoke display_message command
166     *
167     * @param string  $message  Message to display
168     * @param string  $type     Message type [notice|confirm|error]
169     * @param array   $vars     Key-value pairs to be replaced in localized text
170     * @param boolean $override Override last set message
171     * @param int     $timeout  Message displaying time in seconds
172     * @uses self::command()
173     */
174    public function show_message($message, $type='notice', $vars=null, $override=true, $timeout=0)
175    {
176        if ($override || !$this->message) {
177            if (rcube_label_exists($message)) {
178                if (!empty($vars))
179                    $vars = array_map('Q', $vars);
180                $msgtext = rcube_label(array('name' => $message, 'vars' => $vars));
181            }
182            else
183                $msgtext = $message;
184
185            $this->message = $message;
186            $this->command('display_message', $msgtext, $type, $timeout * 1000);
187        }
188    }
189
190
191    /**
192     * Delete all stored env variables and commands
193     */
194    public function reset()
195    {
196        $this->env = array();
197        $this->texts = array();
198        $this->commands = array();
199    }
200
201
202    /**
203     * Redirect to a certain url
204     *
205     * @param mixed $p Either a string with the action or url parameters as key-value pairs
206     * @param int $delay Delay in seconds
207     * @see rcmail::url()
208     */
209    public function redirect($p = array(), $delay = 1)
210    {
211        $location = rcmail::get_instance()->url($p);
212        $this->remote_response("window.setTimeout(\"location.href='{$location}'\", $delay);");
213        exit;
214    }
215
216
217    /**
218     * Send an AJAX response to the client.
219     */
220    public function send()
221    {
222        $this->remote_response();
223        exit;
224    }
225
226
227    /**
228     * Send an AJAX response with executable JS code
229     *
230     * @param  string  $add Additional JS code
231     * @param  boolean True if output buffer should be flushed
232     * @return void
233     * @deprecated
234     */
235    public function remote_response($add='')
236    {
237        static $s_header_sent = false;
238
239        if (!$s_header_sent) {
240            $s_header_sent = true;
241            send_nocacheing_headers();
242            header('Content-Type: text/plain; charset=' . $this->get_charset());
243        }
244
245        // unset default env vars
246        unset($this->env['task'], $this->env['action'], $this->env['comm_path']);
247
248        $rcmail = rcmail::get_instance();
249        $response['action'] = $rcmail->action;
250
251        if ($unlock = get_input_value('_unlock', RCUBE_INPUT_GPC)) {
252            $response['unlock'] = $unlock;
253        }
254
255        if (!empty($this->env))
256            $response['env'] = $this->env;
257
258        if (!empty($this->texts))
259            $response['texts'] = $this->texts;
260
261        // send function calls
262        $response['exec'] = $this->get_js_commands() . $add;
263
264        if (!empty($this->callbacks))
265            $response['callbacks'] = $this->callbacks;
266
267        echo json_serialize($response);
268    }
269
270
271    /**
272     * Return executable javascript code for all registered commands
273     *
274     * @return string $out
275     */
276    private function get_js_commands()
277    {
278        $out = '';
279
280        foreach ($this->commands as $i => $args) {
281            $method = array_shift($args);
282            foreach ($args as $i => $arg) {
283                $args[$i] = json_serialize($arg);
284            }
285
286            $out .= sprintf(
287                "this.%s(%s);\n",
288                preg_replace('/^parent\./', '', $method),
289                implode(',', $args)
290            );
291        }
292
293        return $out;
294    }
295}
Note: See TracBrowser for help on using the repository browser.