"Fossies" - the Fresh Open Source Software Archive 
Member "phpMyAdmin-5.1.0-all-languages/libraries/classes/Controllers/HomeController.php" (24 Feb 2021, 18244 Bytes) of package /linux/www/phpMyAdmin-5.1.0-all-languages.zip:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
See also the last
Fossies "Diffs" side-by-side code changes report for "HomeController.php":
5.0.4-english_vs_5.1.0-english.
1 <?php
2
3 declare(strict_types=1);
4
5 namespace PhpMyAdmin\Controllers;
6
7 use PhpMyAdmin\Charsets;
8 use PhpMyAdmin\Charsets\Charset;
9 use PhpMyAdmin\Charsets\Collation;
10 use PhpMyAdmin\CheckUserPrivileges;
11 use PhpMyAdmin\Config;
12 use PhpMyAdmin\DatabaseInterface;
13 use PhpMyAdmin\Git;
14 use PhpMyAdmin\Html\Generator;
15 use PhpMyAdmin\LanguageManager;
16 use PhpMyAdmin\Message;
17 use PhpMyAdmin\RecentFavoriteTable;
18 use PhpMyAdmin\Relation;
19 use PhpMyAdmin\Response;
20 use PhpMyAdmin\Server\Select;
21 use PhpMyAdmin\Template;
22 use PhpMyAdmin\ThemeManager;
23 use PhpMyAdmin\Url;
24 use PhpMyAdmin\UserPreferences;
25 use PhpMyAdmin\Util;
26 use const E_USER_NOTICE;
27 use const E_USER_WARNING;
28 use const PHP_VERSION;
29 use function count;
30 use function extension_loaded;
31 use function file_exists;
32 use function ini_get;
33 use function preg_match;
34 use function sprintf;
35 use function strlen;
36 use function strtotime;
37 use function trigger_error;
38
39 class HomeController extends AbstractController
40 {
41 /** @var Config */
42 private $config;
43
44 /** @var ThemeManager */
45 private $themeManager;
46
47 /** @var DatabaseInterface */
48 private $dbi;
49
50 /**
51 * @param Response $response
52 * @param Config $config
53 * @param DatabaseInterface $dbi
54 */
55 public function __construct($response, Template $template, $config, ThemeManager $themeManager, $dbi)
56 {
57 parent::__construct($response, $template);
58 $this->config = $config;
59 $this->themeManager = $themeManager;
60 $this->dbi = $dbi;
61 }
62
63 public function index(): void
64 {
65 global $cfg, $server, $collation_connection, $message, $show_query, $db, $table, $err_url;
66
67 if ($this->response->isAjax() && ! empty($_REQUEST['access_time'])) {
68 return;
69 }
70
71 // This is for $cfg['ShowDatabasesNavigationAsTree'] = false;
72 // See: https://github.com/phpmyadmin/phpmyadmin/issues/16520
73 // The DB is defined here and sent to the JS front-end to refresh the DB tree
74 $db = $_POST['db'] ?? '';
75 $table = '';
76 $show_query = '1';
77 $err_url = Url::getFromRoute('/');
78
79 if ($server > 0 && $this->dbi->isSuperUser()) {
80 $this->dbi->selectDb('mysql');
81 }
82
83 $languageManager = LanguageManager::getInstance();
84
85 if (! empty($message)) {
86 $displayMessage = Generator::getMessage($message);
87 unset($message);
88 }
89 if (isset($_SESSION['partial_logout'])) {
90 $partialLogout = Message::success(__(
91 'You were logged out from one server, to logout completely '
92 . 'from phpMyAdmin, you need to logout from all servers.'
93 ))->getDisplay();
94 unset($_SESSION['partial_logout']);
95 }
96
97 $syncFavoriteTables = RecentFavoriteTable::getInstance('favorite')
98 ->getHtmlSyncFavoriteTables();
99
100 $hasServer = $server > 0 || count($cfg['Servers']) > 1;
101 if ($hasServer) {
102 $hasServerSelection = $cfg['ServerDefault'] == 0
103 || (! $cfg['NavigationDisplayServers']
104 && (count($cfg['Servers']) > 1
105 || ($server == 0 && count($cfg['Servers']) === 1)));
106 if ($hasServerSelection) {
107 $serverSelection = Select::render(true, true);
108 }
109
110 if ($server > 0) {
111 $checkUserPrivileges = new CheckUserPrivileges($this->dbi);
112 $checkUserPrivileges->getPrivileges();
113
114 $charsets = Charsets::getCharsets($this->dbi, $cfg['Server']['DisableIS']);
115 $collations = Charsets::getCollations($this->dbi, $cfg['Server']['DisableIS']);
116 $charsetsList = [];
117 /** @var Charset $charset */
118 foreach ($charsets as $charset) {
119 $collationsList = [];
120 /** @var Collation $collation */
121 foreach ($collations[$charset->getName()] as $collation) {
122 $collationsList[] = [
123 'name' => $collation->getName(),
124 'description' => $collation->getDescription(),
125 'is_selected' => $collation_connection === $collation->getName(),
126 ];
127 }
128 $charsetsList[] = [
129 'name' => $charset->getName(),
130 'description' => $charset->getDescription(),
131 'collations' => $collationsList,
132 ];
133 }
134 }
135 }
136
137 $languageSelector = '';
138 if (empty($cfg['Lang']) && $languageManager->hasChoice()) {
139 $languageSelector = $languageManager->getSelectorDisplay($this->template);
140 }
141
142 $themeSelection = '';
143 if ($cfg['ThemeManager']) {
144 $themeSelection = $this->themeManager->getHtmlSelectBox();
145 }
146
147 $databaseServer = [];
148 if ($server > 0 && $cfg['ShowServerInfo']) {
149 $hostInfo = '';
150 if (! empty($cfg['Server']['verbose'])) {
151 $hostInfo .= $cfg['Server']['verbose'];
152 if ($cfg['ShowServerInfo']) {
153 $hostInfo .= ' (';
154 }
155 }
156 if ($cfg['ShowServerInfo'] || empty($cfg['Server']['verbose'])) {
157 $hostInfo .= $this->dbi->getHostInfo();
158 }
159 if (! empty($cfg['Server']['verbose']) && $cfg['ShowServerInfo']) {
160 $hostInfo .= ')';
161 }
162
163 $serverCharset = Charsets::getServerCharset($this->dbi, $cfg['Server']['DisableIS']);
164 $databaseServer = [
165 'host' => $hostInfo,
166 'type' => Util::getServerType(),
167 'connection' => Generator::getServerSSL(),
168 'version' => $this->dbi->getVersionString() . ' - ' . $this->dbi->getVersionComment(),
169 'protocol' => $this->dbi->getProtoInfo(),
170 'user' => $this->dbi->fetchValue('SELECT USER();'),
171 'charset' => $serverCharset->getDescription() . ' (' . $serverCharset->getName() . ')',
172 ];
173 }
174
175 $webServer = [];
176 if ($cfg['ShowServerInfo']) {
177 $webServer['software'] = $_SERVER['SERVER_SOFTWARE'];
178
179 if ($server > 0) {
180 $clientVersion = $this->dbi->getClientInfo();
181 if (preg_match('#\d+\.\d+\.\d+#', $clientVersion)) {
182 $clientVersion = 'libmysql - ' . $clientVersion;
183 }
184
185 $webServer['database'] = $clientVersion;
186 $webServer['php_extensions'] = Util::listPHPExtensions();
187 $webServer['php_version'] = PHP_VERSION;
188 }
189 }
190
191 $relation = new Relation($this->dbi);
192 if ($server > 0) {
193 $cfgRelation = $relation->getRelationsParam();
194 if (! $cfgRelation['allworks']
195 && $cfg['PmaNoRelation_DisableWarning'] == false
196 ) {
197 $messageText = __(
198 'The phpMyAdmin configuration storage is not completely '
199 . 'configured, some extended features have been deactivated. '
200 . '%sFind out why%s. '
201 );
202 if ($cfg['ZeroConf'] == true) {
203 $messageText .= '<br>' .
204 __(
205 'Or alternately go to \'Operations\' tab of any database '
206 . 'to set it up there.'
207 );
208 }
209 $messageInstance = Message::notice($messageText);
210 $messageInstance->addParamHtml(
211 '<a href="' . Url::getFromRoute('/check-relations')
212 . '" data-post="' . Url::getCommon() . '">'
213 );
214 $messageInstance->addParamHtml('</a>');
215 /* Show error if user has configured something, notice elsewhere */
216 if (! empty($cfg['Servers'][$server]['pmadb'])) {
217 $messageInstance->isError(true);
218 }
219 $configStorageMessage = $messageInstance->getDisplay();
220 }
221 }
222
223 $this->checkRequirements();
224
225 $git = new Git($this->config);
226
227 $this->render('home/index', [
228 'message' => $displayMessage ?? '',
229 'partial_logout' => $partialLogout ?? '',
230 'is_git_revision' => $git->isGitRevision(),
231 'server' => $server,
232 'sync_favorite_tables' => $syncFavoriteTables,
233 'has_server' => $hasServer,
234 'is_demo' => $cfg['DBG']['demo'],
235 'has_server_selection' => $hasServerSelection ?? false,
236 'server_selection' => $serverSelection ?? '',
237 'has_change_password_link' => $cfg['Server']['auth_type'] !== 'config' && $cfg['ShowChgPassword'],
238 'charsets' => $charsetsList ?? [],
239 'language_selector' => $languageSelector,
240 'theme_selection' => $themeSelection,
241 'database_server' => $databaseServer,
242 'web_server' => $webServer,
243 'show_php_info' => $cfg['ShowPhpInfo'],
244 'is_version_checked' => $cfg['VersionCheck'],
245 'phpmyadmin_version' => PMA_VERSION,
246 'config_storage_message' => $configStorageMessage ?? '',
247 ]);
248 }
249
250 public function setTheme(): void
251 {
252 $this->themeManager->setActiveTheme($_POST['set_theme']);
253 $this->themeManager->setThemeCookie();
254
255 $userPreferences = new UserPreferences();
256 $preferences = $userPreferences->load();
257 $preferences['config_data']['ThemeDefault'] = $_POST['set_theme'];
258 $userPreferences->save($preferences['config_data']);
259
260 $this->response->header('Location: index.php?route=/' . Url::getCommonRaw([], '&'));
261 }
262
263 public function setCollationConnection(): void
264 {
265 $this->config->setUserValue(
266 null,
267 'DefaultConnectionCollation',
268 $_POST['collation_connection'],
269 'utf8mb4_unicode_ci'
270 );
271
272 $this->response->header('Location: index.php?route=/' . Url::getCommonRaw([], '&'));
273 }
274
275 public function reloadRecentTablesList(): void
276 {
277 if (! $this->response->isAjax()) {
278 return;
279 }
280
281 $this->response->addJSON([
282 'list' => RecentFavoriteTable::getInstance('recent')->getHtmlList(),
283 ]);
284 }
285
286 public function gitRevision(): void
287 {
288 if (! $this->response->isAjax()) {
289 return;
290 }
291
292 $git = new Git($this->config);
293
294 if (! $git->isGitRevision()) {
295 return;
296 }
297
298 $commit = $git->checkGitRevision();
299
300 if (! $this->config->get('PMA_VERSION_GIT') || $commit === null) {
301 $this->response->setRequestStatus(false);
302
303 return;
304 }
305
306 $commit['author']['date'] = Util::localisedDate(strtotime($commit['author']['date']));
307 $commit['committer']['date'] = Util::localisedDate(strtotime($commit['committer']['date']));
308
309 $this->render('home/git_info', $commit);
310 }
311
312 private function checkRequirements(): void
313 {
314 global $cfg, $server, $lang;
315
316 /**
317 * mbstring is used for handling multibytes inside parser, so it is good
318 * to tell user something might be broken without it, see bug #1063149.
319 */
320 if (! extension_loaded('mbstring')) {
321 trigger_error(
322 __(
323 'The mbstring PHP extension was not found and you seem to be using'
324 . ' a multibyte charset. Without the mbstring extension phpMyAdmin'
325 . ' is unable to split strings correctly and it may result in'
326 . ' unexpected results.'
327 ),
328 E_USER_WARNING
329 );
330 }
331
332 /**
333 * Missing functionality
334 */
335 if (! extension_loaded('curl') && ! ini_get('allow_url_fopen')) {
336 trigger_error(
337 __(
338 'The curl extension was not found and allow_url_fopen is '
339 . 'disabled. Due to this some features such as error reporting '
340 . 'or version check are disabled.'
341 )
342 );
343 }
344
345 if ($cfg['LoginCookieValidityDisableWarning'] == false) {
346 /**
347 * Check whether session.gc_maxlifetime limits session validity.
348 */
349 $gc_time = (int) ini_get('session.gc_maxlifetime');
350 if ($gc_time < $cfg['LoginCookieValidity']) {
351 trigger_error(
352 __(
353 'Your PHP parameter [a@https://secure.php.net/manual/en/session.' .
354 'configuration.php#ini.session.gc-maxlifetime@_blank]session.' .
355 'gc_maxlifetime[/a] is lower than cookie validity configured ' .
356 'in phpMyAdmin, because of this, your login might expire sooner ' .
357 'than configured in phpMyAdmin.'
358 ),
359 E_USER_WARNING
360 );
361 }
362 }
363
364 /**
365 * Check whether LoginCookieValidity is limited by LoginCookieStore.
366 */
367 if ($cfg['LoginCookieStore'] != 0
368 && $cfg['LoginCookieStore'] < $cfg['LoginCookieValidity']
369 ) {
370 trigger_error(
371 __(
372 'Login cookie store is lower than cookie validity configured in ' .
373 'phpMyAdmin, because of this, your login will expire sooner than ' .
374 'configured in phpMyAdmin.'
375 ),
376 E_USER_WARNING
377 );
378 }
379
380 /**
381 * Warning if using the default MySQL controluser account
382 */
383 if (isset($cfg['Server']['controluser'], $cfg['Server']['controlpass'])
384 && $server != 0
385 && $cfg['Server']['controluser'] === 'pma'
386 && $cfg['Server']['controlpass'] === 'pmapass'
387 ) {
388 trigger_error(
389 __(
390 'Your server is running with default values for the ' .
391 'controluser and password (controlpass) and is open to ' .
392 'intrusion; you really should fix this security weakness' .
393 ' by changing the password for controluser \'pma\'.'
394 ),
395 E_USER_WARNING
396 );
397 }
398
399 /**
400 * Check if user does not have defined blowfish secret and it is being used.
401 */
402 if (! empty($_SESSION['encryption_key'])) {
403 if (empty($cfg['blowfish_secret'])) {
404 trigger_error(
405 __(
406 'The configuration file now needs a secret passphrase (blowfish_secret).'
407 ),
408 E_USER_WARNING
409 );
410 } elseif (strlen($cfg['blowfish_secret']) < 32) {
411 trigger_error(
412 __(
413 'The secret passphrase in configuration (blowfish_secret) is too short.'
414 ),
415 E_USER_WARNING
416 );
417 }
418 }
419
420 /**
421 * Check for existence of config directory which should not exist in
422 * production environment.
423 */
424 if (@file_exists(ROOT_PATH . 'config')) {
425 trigger_error(
426 __(
427 'Directory [code]config[/code], which is used by the setup script, ' .
428 'still exists in your phpMyAdmin directory. It is strongly ' .
429 'recommended to remove it once phpMyAdmin has been configured. ' .
430 'Otherwise the security of your server may be compromised by ' .
431 'unauthorized people downloading your configuration.'
432 ),
433 E_USER_WARNING
434 );
435 }
436
437 /**
438 * Warning about Suhosin only if its simulation mode is not enabled
439 */
440 if ($cfg['SuhosinDisableWarning'] == false
441 && ini_get('suhosin.request.max_value_length')
442 && ini_get('suhosin.simulation') == '0'
443 ) {
444 trigger_error(
445 sprintf(
446 __(
447 'Server running with Suhosin. Please refer ' .
448 'to %sdocumentation%s for possible issues.'
449 ),
450 '[doc@faq1-38]',
451 '[/doc]'
452 ),
453 E_USER_WARNING
454 );
455 }
456
457 /* Missing template cache */
458 if ($this->config->getTempDir('twig') === null) {
459 trigger_error(
460 sprintf(
461 __(
462 'The $cfg[\'TempDir\'] (%s) is not accessible. ' .
463 'phpMyAdmin is not able to cache templates and will ' .
464 'be slow because of this.'
465 ),
466 $this->config->get('TempDir')
467 ),
468 E_USER_WARNING
469 );
470 }
471
472 /**
473 * Warning about incomplete translations.
474 *
475 * The data file is created while creating release by ./scripts/remove-incomplete-mo
476 */
477 if (! @file_exists(ROOT_PATH . 'libraries/language_stats.inc.php')) {
478 return;
479 }
480
481 include ROOT_PATH . 'libraries/language_stats.inc.php';
482 /*
483 * This message is intentionally not translated, because we're
484 * handling incomplete translations here and focus on english
485 * speaking users.
486 */
487 if (! isset($GLOBALS['language_stats'][$lang])
488 || $GLOBALS['language_stats'][$lang] >= $cfg['TranslationWarningThreshold']
489 ) {
490 return;
491 }
492
493 trigger_error(
494 'You are using an incomplete translation, please help to make it '
495 . 'better by [a@https://www.phpmyadmin.net/translate/'
496 . '@_blank]contributing[/a].',
497 E_USER_NOTICE
498 );
499 }
500 }