Translated using Weblate (Estonian)
[phpmyadmin.git] / libraries / classes / Footer.php
blob965bcb1064436ff8b4287ca087fc9b71ff257842
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Used to render the footer of PMA's pages
6 * @package PhpMyAdmin
7 */
8 declare(strict_types=1);
10 namespace PhpMyAdmin;
12 use Traversable;
14 /**
15 * Class used to output the footer
17 * @package PhpMyAdmin
19 class Footer
21 /**
22 * Scripts instance
24 * @access private
25 * @var Scripts
27 private $_scripts;
28 /**
29 * Whether we are servicing an ajax request.
31 * @access private
32 * @var bool
34 private $_isAjax;
35 /**
36 * Whether to only close the BODY and HTML tags
37 * or also include scripts, errors and links
39 * @access private
40 * @var bool
42 private $_isMinimal;
43 /**
44 * Whether to display anything
46 * @access private
47 * @var bool
49 private $_isEnabled;
51 /**
52 * @var Relation
54 private $relation;
56 /**
57 * @var Template
59 private $template;
61 /**
62 * Creates a new class instance
64 public function __construct()
66 $this->template = new Template();
67 $this->_isEnabled = true;
68 $this->_scripts = new Scripts();
69 $this->_isMinimal = false;
70 $this->relation = new Relation($GLOBALS['dbi']);
73 /**
74 * Returns the message for demo server to error messages
76 * @return string
78 private function _getDemoMessage(): string
80 $message = '<a href="/">' . __('phpMyAdmin Demo Server') . '</a>: ';
81 if (@file_exists(ROOT_PATH . 'revision-info.php')) {
82 include ROOT_PATH . 'revision-info.php';
83 $message .= sprintf(
84 __('Currently running Git revision %1$s from the %2$s branch.'),
85 '<a target="_blank" rel="noopener noreferrer" href="' . $repobase . $fullrevision . '">'
86 . $revision . '</a>',
87 '<a target="_blank" rel="noopener noreferrer" href="' . $repobranchbase . $branch . '">'
88 . $branch . '</a>'
90 } else {
91 $message .= __('Git information missing!');
94 return Message::notice($message)->getDisplay();
97 /**
98 * Remove recursions and iterator objects from an object
100 * @param object|array $object Object to clean
101 * @param array $stack Stack used to keep track of recursion,
102 * need not be passed for the first time
104 * @return object Reference passed object
106 private static function _removeRecursion(&$object, array $stack = [])
108 if ((is_object($object) || is_array($object)) && $object) {
109 if ($object instanceof Traversable) {
110 $object = "***ITERATOR***";
111 } elseif (! in_array($object, $stack, true)) {
112 $stack[] = $object;
113 foreach ($object as &$subobject) {
114 self::_removeRecursion($subobject, $stack);
116 } else {
117 $object = "***RECURSION***";
120 return $object;
124 * Renders the debug messages
126 * @return string
128 public function getDebugMessage(): string
130 $retval = '\'null\'';
131 if ($GLOBALS['cfg']['DBG']['sql']
132 && empty($_REQUEST['no_debug'])
133 && ! empty($_SESSION['debug'])
135 // Remove recursions and iterators from $_SESSION['debug']
136 self::_removeRecursion($_SESSION['debug']);
138 $retval = json_encode($_SESSION['debug']);
139 $_SESSION['debug'] = [];
140 return json_last_error() ? '\'false\'' : $retval;
142 $_SESSION['debug'] = [];
143 return $retval;
147 * Returns the url of the current page
149 * @return string
151 public function getSelfUrl(): string
153 $db = isset($GLOBALS['db']) && strlen($GLOBALS['db']) ? $GLOBALS['db'] : '';
154 $table = isset($GLOBALS['table']) && strlen($GLOBALS['table']) ? $GLOBALS['table'] : '';
155 $target = isset($_REQUEST['target']) && strlen($_REQUEST['target']) ? $_REQUEST['target'] : '';
156 $params = [
157 'db' => $db,
158 'table' => $table,
159 'server' => $GLOBALS['server'],
160 'target' => $target,
162 // needed for server privileges tabs
163 if (isset($_GET['viewing_mode'])
164 && in_array($_GET['viewing_mode'], ['server', 'db', 'table'])
166 $params['viewing_mode'] = $_GET['viewing_mode'];
169 * @todo coming from /server/privileges, here $db is not set,
170 * add the following condition below when that is fixed
171 * && $_GET['checkprivsdb'] == $db
173 if (isset($_GET['checkprivsdb'])
175 $params['checkprivsdb'] = $_GET['checkprivsdb'];
178 * @todo coming from /server/privileges, here $table is not set,
179 * add the following condition below when that is fixed
180 * && $_REQUEST['checkprivstable'] == $table
182 if (isset($_GET['checkprivstable'])
184 $params['checkprivstable'] = $_GET['checkprivstable'];
186 if (isset($_REQUEST['single_table'])
187 && in_array($_REQUEST['single_table'], [true, false])
189 $params['single_table'] = $_REQUEST['single_table'];
191 return basename(Core::getenv('SCRIPT_NAME')) . Url::getCommonRaw($params);
195 * Renders the link to open a new page
197 * @param string $url The url of the page
199 * @return string
201 private function _getSelfLink(string $url): string
203 $retval = '';
204 $retval .= '<div id="selflink" class="print_ignore">';
205 $retval .= '<a href="' . htmlspecialchars($url) . '"'
206 . ' title="' . __('Open new phpMyAdmin window') . '" target="_blank" rel="noopener noreferrer">';
207 if (Util::showIcons('TabsMode')) {
208 $retval .= Util::getImage(
209 'window-new',
210 __('Open new phpMyAdmin window')
212 } else {
213 $retval .= __('Open new phpMyAdmin window');
215 $retval .= '</a>';
216 $retval .= '</div>';
217 return $retval;
221 * Renders the link to open a new page
223 * @return string
225 public function getErrorMessages(): string
227 $retval = '';
228 if ($GLOBALS['error_handler']->hasDisplayErrors()) {
229 $retval .= $GLOBALS['error_handler']->getDispErrors();
233 * Report php errors
235 $GLOBALS['error_handler']->reportErrors();
237 return $retval;
241 * Saves query in history
243 * @return void
245 private function _setHistory(): void
247 if (! Core::isValid($_REQUEST['no_history'])
248 && empty($GLOBALS['error_message'])
249 && ! empty($GLOBALS['sql_query'])
250 && isset($GLOBALS['dbi'])
251 && $GLOBALS['dbi']->isUserType('logged')
253 $this->relation->setHistory(
254 Core::ifSetOr($GLOBALS['db'], ''),
255 Core::ifSetOr($GLOBALS['table'], ''),
256 $GLOBALS['cfg']['Server']['user'],
257 $GLOBALS['sql_query']
263 * Disables the rendering of the footer
265 * @return void
267 public function disable(): void
269 $this->_isEnabled = false;
273 * Set the ajax flag to indicate whether
274 * we are servicing an ajax request
276 * @param bool $isAjax Whether we are servicing an ajax request
278 * @return void
280 public function setAjax(bool $isAjax): void
282 $this->_isAjax = $isAjax;
286 * Turn on minimal display mode
288 * @return void
290 public function setMinimal(): void
292 $this->_isMinimal = true;
296 * Returns the Scripts object
298 * @return Scripts object
300 public function getScripts(): Scripts
302 return $this->_scripts;
306 * Renders the footer
308 * @return string
310 public function getDisplay(): string
312 $this->_setHistory();
313 if ($this->_isEnabled) {
314 if (! $this->_isAjax && ! $this->_isMinimal) {
315 if (Core::getenv('SCRIPT_NAME')
316 && empty($_POST)
317 && ! $this->_isAjax
319 $url = $this->getSelfUrl();
320 $header = Response::getInstance()->getHeader();
321 $scripts = $header->getScripts()->getFiles();
322 $menuHash = $header->getMenu()->getHash();
323 // prime the client-side cache
324 $this->_scripts->addCode(
325 sprintf(
326 'if (! (history && history.pushState)) '
327 . 'MicroHistory.primer = {'
328 . ' url: "%s",'
329 . ' scripts: %s,'
330 . ' menuHash: "%s"'
331 . '};',
332 Sanitize::escapeJsString($url),
333 json_encode($scripts),
334 Sanitize::escapeJsString($menuHash)
338 if (Core::getenv('SCRIPT_NAME')
339 && ! $this->_isAjax
341 $url = $this->getSelfUrl();
342 $selfLink = $this->_getSelfLink($url);
344 $this->_scripts->addCode(
345 'var debugSQLInfo = ' . $this->getDebugMessage() . ';'
348 $errorMessages = $this->getErrorMessages();
349 $scripts = $this->_scripts->getDisplay();
351 if ($GLOBALS['cfg']['DBG']['demo']) {
352 $demoMessage = $this->_getDemoMessage();
355 $footer = Config::renderFooter();
357 return $this->template->render('footer', [
358 'is_ajax' => $this->_isAjax,
359 'is_minimal' => $this->_isMinimal,
360 'self_link' => $selfLink ?? '',
361 'error_messages' => $errorMessages ?? '',
362 'scripts' => $scripts ?? '',
363 'is_demo' => $GLOBALS['cfg']['DBG']['demo'],
364 'demo_message' => $demoMessage ?? '',
365 'footer' => $footer ?? '',
368 return '';