Translated using Weblate (Slovenian)
[phpmyadmin.git] / libraries / Response.php
blob97ab19ab6de4346426e65764ae1f9dd07f410b05
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Manages the rendering of pages in PMA
6 * @package PhpMyAdmin
7 */
8 namespace PMA\libraries;
10 /**
11 * Singleton class used to manage the rendering of pages in PMA
13 * @package PhpMyAdmin
15 class Response
17 /**
18 * Response instance
20 * @access private
21 * @static
22 * @var Response
24 private static $_instance;
25 /**
26 * Header instance
28 * @access private
29 * @var Header
31 private $_header;
32 /**
33 * HTML data to be used in the response
35 * @access private
36 * @var string
38 private $_HTML;
39 /**
40 * An array of JSON key-value pairs
41 * to be sent back for ajax requests
43 * @access private
44 * @var array
46 private $_JSON;
47 /**
48 * PMA\libraries\Footer instance
50 * @access private
51 * @var Footer
53 private $_footer;
54 /**
55 * Whether we are servicing an ajax request.
57 * @access private
58 * @var bool
60 private $_isAjax;
61 /**
62 * Whether response object is disabled
64 * @access private
65 * @var bool
67 private $_isDisabled;
68 /**
69 * Whether there were any errors during the processing of the request
70 * Only used for ajax responses
72 * @access private
73 * @var bool
75 private $_isSuccess;
76 /**
77 * Workaround for PHP bug
79 * @access private
80 * @var string|bool
82 private $_CWD;
84 /**
85 * Creates a new class instance
87 private function __construct()
89 if (! defined('TESTSUITE')) {
90 $buffer = OutputBuffering::getInstance();
91 $buffer->start();
92 register_shutdown_function(array($this, 'response'));
94 $this->_header = new Header();
95 $this->_HTML = '';
96 $this->_JSON = array();
97 $this->_footer = new Footer();
99 $this->_isSuccess = true;
100 $this->_isDisabled = false;
101 $this->setAjax(! empty($_REQUEST['ajax_request']));
102 $this->_CWD = getcwd();
106 * Set the ajax flag to indicate whether
107 * we are servicing an ajax request
109 * @param bool $isAjax Whether we are servicing an ajax request
111 * @return void
113 public function setAjax($isAjax)
115 $this->_isAjax = (boolean) $isAjax;
116 $this->_header->setAjax($this->_isAjax);
117 $this->_footer->setAjax($this->_isAjax);
121 * Returns the singleton Response object
123 * @return Response object
125 public static function getInstance()
127 if (empty(self::$_instance)) {
128 self::$_instance = new Response();
130 return self::$_instance;
134 * Set the status of an ajax response,
135 * whether it is a success or an error
137 * @param bool $state Whether the request was successfully processed
139 * @return void
141 public function setRequestStatus($state)
143 $this->_isSuccess = ($state == true);
147 * Returns true or false depending on whether
148 * we are servicing an ajax request
150 * @return bool
152 public function isAjax()
154 return $this->_isAjax;
158 * Returns the path to the current working directory
159 * Necessary to work around a PHP bug where the CWD is
160 * reset after the initial script exits
162 * @return string
164 public function getCWD()
166 return $this->_CWD;
170 * Disables the rendering of the header
171 * and the footer in responses
173 * @return void
175 public function disable()
177 $this->_header->disable();
178 $this->_footer->disable();
179 $this->_isDisabled = true;
183 * Returns a PMA\libraries\Header object
185 * @return Header
187 public function getHeader()
189 return $this->_header;
193 * Returns a PMA\libraries\Footer object
195 * @return Footer
197 public function getFooter()
199 return $this->_footer;
203 * Add HTML code to the response
205 * @param string $content A string to be appended to
206 * the current output buffer
208 * @return void
210 public function addHTML($content)
212 if (is_array($content)) {
213 foreach ($content as $msg) {
214 $this->addHTML($msg);
216 } elseif ($content instanceof Message) {
217 $this->_HTML .= $content->getDisplay();
218 } else {
219 $this->_HTML .= $content;
224 * Add JSON code to the response
226 * @param mixed $json Either a key (string) or an
227 * array or key-value pairs
228 * @param mixed $value Null, if passing an array in $json otherwise
229 * it's a string value to the key
231 * @return void
233 public function addJSON($json, $value = null)
235 if (is_array($json)) {
236 foreach ($json as $key => $value) {
237 $this->addJSON($key, $value);
239 } else {
240 if ($value instanceof Message) {
241 $this->_JSON[$json] = $value->getDisplay();
242 } else {
243 $this->_JSON[$json] = $value;
250 * Renders the HTML response text
252 * @return string
254 private function _getDisplay()
256 // The header may contain nothing at all,
257 // if its content was already rendered
258 // and, in this case, the header will be
259 // in the content part of the request
260 $retval = $this->_header->getDisplay();
261 $retval .= $this->_HTML;
262 $retval .= $this->_footer->getDisplay();
263 return $retval;
267 * Sends an HTML response to the browser
269 * @return void
271 private function _htmlResponse()
273 echo $this->_getDisplay();
277 * Sends a JSON response to the browser
279 * @return void
281 private function _ajaxResponse()
283 /* Avoid wrapping in case we're disabled */
284 if ($this->_isDisabled) {
285 echo $this->_getDisplay();
286 return;
289 if (! isset($this->_JSON['message'])) {
290 $this->_JSON['message'] = $this->_getDisplay();
291 } else if ($this->_JSON['message'] instanceof Message) {
292 $this->_JSON['message'] = $this->_JSON['message']->getDisplay();
295 if ($this->_isSuccess) {
296 $this->_JSON['success'] = true;
297 } else {
298 $this->_JSON['success'] = false;
299 $this->_JSON['error'] = $this->_JSON['message'];
300 unset($this->_JSON['message']);
303 if ($this->_isSuccess) {
304 $this->addJSON('_title', $this->getHeader()->getTitleTag());
306 if (isset($GLOBALS['dbi'])) {
307 $menuHash = $this->getHeader()->getMenu()->getHash();
308 $this->addJSON('_menuHash', $menuHash);
309 $hashes = array();
310 if (isset($_REQUEST['menuHashes'])) {
311 $hashes = explode('-', $_REQUEST['menuHashes']);
313 if (! in_array($menuHash, $hashes)) {
314 $this->addJSON(
315 '_menu',
316 $this->getHeader()
317 ->getMenu()
318 ->getDisplay()
323 $this->addJSON('_scripts', $this->getHeader()->getScripts()->getFiles());
324 $this->addJSON('_selflink', $this->getFooter()->getSelfUrl());
325 $this->addJSON('_displayMessage', $this->getHeader()->getMessage());
327 $debug = $this->_footer->getDebugMessage();
328 if (empty($_REQUEST['no_debug'])
329 && strlen($debug) > 0
331 $this->addJSON('_debug', $debug);
334 $errors = $this->_footer->getErrorMessages();
335 if (strlen($errors) > 0) {
336 $this->addJSON('_errors', $errors);
338 $promptPhpErrors = $GLOBALS['error_handler']->hasErrorsForPrompt();
339 $this->addJSON('_promptPhpErrors', $promptPhpErrors);
341 if (empty($GLOBALS['error_message'])) {
342 // set current db, table and sql query in the querywindow
343 // (this is for the bottom console)
344 $query = '';
345 $maxChars = $GLOBALS['cfg']['MaxCharactersInDisplayedSQL'];
346 if (isset($GLOBALS['sql_query'])
347 && mb_strlen($GLOBALS['sql_query']) < $maxChars
349 $query = $GLOBALS['sql_query'];
351 $this->addJSON(
352 '_reloadQuerywindow',
353 array(
354 'db' => PMA_ifSetOr($GLOBALS['db'], ''),
355 'table' => PMA_ifSetOr($GLOBALS['table'], ''),
356 'sql_query' => $query
359 if (! empty($GLOBALS['focus_querywindow'])) {
360 $this->addJSON('_focusQuerywindow', $query);
362 if (! empty($GLOBALS['reload'])) {
363 $this->addJSON('_reloadNavigation', 1);
365 $this->addJSON('_params', $this->getHeader()->getJsParams());
369 // Set the Content-Type header to JSON so that jQuery parses the
370 // response correctly.
371 PMA_headerJSON();
373 $result = json_encode($this->_JSON);
374 if ($result === false) {
375 switch (json_last_error()) {
376 case JSON_ERROR_NONE:
377 $error = 'No errors';
378 break;
379 case JSON_ERROR_DEPTH:
380 $error = 'Maximum stack depth exceeded';
381 break;
382 case JSON_ERROR_STATE_MISMATCH:
383 $error = 'Underflow or the modes mismatch';
384 break;
385 case JSON_ERROR_CTRL_CHAR:
386 $error = 'Unexpected control character found';
387 break;
388 case JSON_ERROR_SYNTAX:
389 $error = 'Syntax error, malformed JSON';
390 break;
391 case JSON_ERROR_UTF8:
392 $error = 'Malformed UTF-8 characters, possibly incorrectly encoded';
393 break;
394 case JSON_ERROR_RECURSION:
395 $error = 'One or more recursive references in the value to be encoded';
396 break;
397 case JSON_ERROR_INF_OR_NAN:
398 $error = 'One or more NAN or INF values in the value to be encoded';
399 break;
400 case JSON_ERROR_UNSUPPORTED_TYPE:
401 $error = 'A value of a type that cannot be encoded was given';
402 default:
403 $error = 'Unknown error';
404 break;
406 echo json_encode(
407 array(
408 'success' => false,
409 'error' => 'JSON encoding failed: ' . $error,
412 } else {
413 echo $result;
418 * Sends an HTML response to the browser
420 * @return void
422 public function response()
424 chdir($this->getCWD());
425 $buffer = OutputBuffering::getInstance();
426 if (empty($this->_HTML)) {
427 $this->_HTML = $buffer->getContents();
429 if ($this->isAjax()) {
430 $this->_ajaxResponse();
431 } else {
432 $this->_htmlResponse();
434 $buffer->flush();
435 exit;
439 * Wrapper around PHP's header() function.
441 * @param string $text header string
443 * @return void
445 public function header($text)
447 header($text);
451 * Wrapper around PHP's headers_sent() function.
453 * @return bool
455 public function headersSent()
457 return headers_sent();