Translated using Weblate (Portuguese)
[phpmyadmin.git] / src / Navigation / Navigation.php
blob067c7974cea2d86cc9e985f3d1791f29c6012431
1 <?php
2 /**
3 * This class is responsible for instantiating
4 * the various components of the navigation panel
5 */
7 declare(strict_types=1);
9 namespace PhpMyAdmin\Navigation;
11 use PhpMyAdmin\Config;
12 use PhpMyAdmin\Config\PageSettings;
13 use PhpMyAdmin\ConfigStorage\Relation;
14 use PhpMyAdmin\Container\ContainerBuilder;
15 use PhpMyAdmin\Current;
16 use PhpMyAdmin\DatabaseInterface;
17 use PhpMyAdmin\Dbal\ConnectionType;
18 use PhpMyAdmin\ResponseRenderer;
19 use PhpMyAdmin\Sanitize;
20 use PhpMyAdmin\Server\Select;
21 use PhpMyAdmin\Template;
22 use PhpMyAdmin\Theme\ThemeManager;
23 use PhpMyAdmin\Url;
24 use PhpMyAdmin\UserPreferences;
25 use PhpMyAdmin\UserPrivilegesFactory;
26 use PhpMyAdmin\Util;
28 use function __;
29 use function count;
30 use function defined;
31 use function file_exists;
32 use function parse_url;
33 use function str_contains;
34 use function trim;
36 use const PHP_URL_HOST;
38 /**
39 * The navigation panel - displays server, db and table selection tree
41 class Navigation
43 private NavigationTree $tree;
44 private readonly UserPrivilegesFactory $userPrivilegesFactory;
46 public function __construct(
47 private Template $template,
48 private Relation $relation,
49 private DatabaseInterface $dbi,
50 private readonly Config $config,
51 ) {
52 $this->tree = new NavigationTree($this->template, $this->dbi, $this->relation, $this->config);
53 $this->userPrivilegesFactory = new UserPrivilegesFactory($this->dbi);
56 /**
57 * Renders the navigation tree, or part of it
59 * @return string The navigation tree
61 public function getDisplay(): string
63 $userPrivileges = $this->userPrivilegesFactory->getPrivileges();
65 $logo = [
66 'is_displayed' => $this->config->settings['NavigationDisplayLogo'],
67 'has_link' => false,
68 'link' => '#',
69 'attributes' => ' target="_blank" rel="noopener noreferrer"',
70 'source' => '',
73 $response = ResponseRenderer::getInstance();
74 if (! $response->isAjax()) {
75 $logo['source'] = $this->getLogoSource();
76 $logo['has_link'] = $this->config->settings['NavigationLogoLink'] !== '';
77 $logo['link'] = trim($this->config->settings['NavigationLogoLink']);
78 if (! Sanitize::checkLink($logo['link'], true)) {
79 $logo['link'] = 'index.php';
82 if ($this->config->settings['NavigationLogoLinkWindow'] === 'main') {
83 if (empty(parse_url($logo['link'], PHP_URL_HOST))) {
84 $logo['link'] .= Url::getCommon(
85 [],
86 ! str_contains($logo['link'], '?') ? '?' : Url::getArgSeparator(),
88 // Internal link detected
89 $logo['attributes'] = '';
90 } else {
91 // External links having a domain name should not be considered
92 // to be links that can use our internal ajax loading
93 $logo['attributes'] = ' class="disableAjax"';
97 if ($this->config->settings['NavigationDisplayServers'] && count($this->config->settings['Servers']) > 1) {
98 $serverSelect = Select::render(true);
101 if (! defined('PMA_DISABLE_NAVI_SETTINGS')) {
102 $pageSettings = new PageSettings(
103 new UserPreferences($this->dbi, new Relation($this->dbi), $this->template),
105 $pageSettings->init('Navi', 'pma_navigation_settings');
106 $response->addHTML($pageSettings->getErrorHTML());
107 $navigationSettings = $pageSettings->getHTML();
111 if (! $response->isAjax() || ! empty($_POST['full']) || ! empty($_POST['reload'])) {
112 if ($this->config->settings['ShowDatabasesNavigationAsTree']) {
113 // provide database tree in navigation
114 $navRender = $this->tree->renderState($userPrivileges);
115 } else {
116 // provide legacy pre-4.0 navigation
117 $navRender = $this->tree->renderDbSelect($userPrivileges);
119 } else {
120 $navRender = $this->tree->renderPath($userPrivileges);
123 return $this->template->render('navigation/main', [
124 'is_ajax' => $response->isAjax(),
125 'logo' => $logo,
126 'config_navigation_width' => $this->config->settings['NavigationWidth'],
127 'is_synced' => $this->config->settings['NavigationLinkWithMainPanel'],
128 'is_highlighted' => $this->config->settings['NavigationTreePointerEnable'],
129 'is_autoexpanded' => $this->config->settings['NavigationTreeAutoexpandSingleDb'],
130 'server' => Current::$server,
131 'auth_type' => $this->config->selectedServer['auth_type'],
132 'is_servers_displayed' => $this->config->settings['NavigationDisplayServers'],
133 'servers' => $this->config->settings['Servers'],
134 'server_select' => $serverSelect ?? '',
135 'navigation_tree' => $navRender,
136 'is_navigation_settings_enabled' => ! defined('PMA_DISABLE_NAVI_SETTINGS'),
137 'navigation_settings' => $navigationSettings ?? '',
138 'is_drag_drop_import_enabled' => $this->config->settings['enable_drag_drop_import'] === true,
139 'is_mariadb' => $this->dbi->isMariaDB(),
144 * Add an item of navigation tree to the hidden items list in PMA database.
146 * @param string $itemName name of the navigation tree item
147 * @param string $itemType type of the navigation tree item
148 * @param string $dbName database name
150 public function hideNavigationItem(
151 string $itemName,
152 string $itemType,
153 string $dbName,
154 ): void {
155 $navigationItemsHidingFeature = $this->relation->getRelationParameters()->navigationItemsHidingFeature;
156 if ($navigationItemsHidingFeature === null) {
157 return;
160 $navTable = Util::backquote($navigationItemsHidingFeature->database)
161 . '.' . Util::backquote($navigationItemsHidingFeature->navigationHiding);
162 $sqlQuery = 'INSERT INTO ' . $navTable
163 . '(`username`, `item_name`, `item_type`, `db_name`, `table_name`)'
164 . ' VALUES ('
165 . $this->dbi->quoteString($this->config->selectedServer['user'], ConnectionType::ControlUser) . ','
166 . $this->dbi->quoteString($itemName, ConnectionType::ControlUser) . ','
167 . $this->dbi->quoteString($itemType, ConnectionType::ControlUser) . ','
168 . $this->dbi->quoteString($dbName, ConnectionType::ControlUser) . ','
169 . "'')";
170 $this->dbi->tryQueryAsControlUser($sqlQuery);
174 * Remove a hidden item of navigation tree from the
175 * list of hidden items in PMA database.
177 * @param string $itemName name of the navigation tree item
178 * @param string $itemType type of the navigation tree item
179 * @param string $dbName database name
181 public function unhideNavigationItem(
182 string $itemName,
183 string $itemType,
184 string $dbName,
185 ): void {
186 $navigationItemsHidingFeature = $this->relation->getRelationParameters()->navigationItemsHidingFeature;
187 if ($navigationItemsHidingFeature === null) {
188 return;
191 $navTable = Util::backquote($navigationItemsHidingFeature->database)
192 . '.' . Util::backquote($navigationItemsHidingFeature->navigationHiding);
193 $sqlQuery = 'DELETE FROM ' . $navTable
194 . ' WHERE'
195 . ' `username`='
196 . $this->dbi->quoteString($this->config->selectedServer['user'], ConnectionType::ControlUser)
197 . ' AND `item_name`=' . $this->dbi->quoteString($itemName, ConnectionType::ControlUser)
198 . ' AND `item_type`=' . $this->dbi->quoteString($itemType, ConnectionType::ControlUser)
199 . ' AND `db_name`=' . $this->dbi->quoteString($dbName, ConnectionType::ControlUser);
200 $this->dbi->tryQueryAsControlUser($sqlQuery);
204 * Returns HTML for the dialog to show hidden navigation items.
206 * @param string $database database name
208 * @return string HTML for the dialog to show hidden navigation items
210 public function getItemUnhideDialog(string $database): string
212 $hidden = $this->getHiddenItems($database);
214 $typeMap = [
215 'group' => __('Groups:'),
216 'event' => __('Events:'),
217 'function' => __('Functions:'),
218 'procedure' => __('Procedures:'),
219 'table' => __('Tables:'),
220 'view' => __('Views:'),
223 return $this->template->render('navigation/item_unhide_dialog', [
224 'database' => $database,
225 'hidden' => $hidden,
226 'types' => $typeMap,
230 /** @return mixed[] */
231 private function getHiddenItems(string $database): array
233 $navigationItemsHidingFeature = $this->relation->getRelationParameters()->navigationItemsHidingFeature;
234 if ($navigationItemsHidingFeature === null) {
235 return [];
238 $navTable = Util::backquote($navigationItemsHidingFeature->database)
239 . '.' . Util::backquote($navigationItemsHidingFeature->navigationHiding);
240 $sqlQuery = 'SELECT `item_name`, `item_type` FROM ' . $navTable
241 . ' WHERE `username`='
242 . $this->dbi->quoteString($this->config->selectedServer['user'], ConnectionType::ControlUser)
243 . ' AND `db_name`=' . $this->dbi->quoteString($database, ConnectionType::ControlUser)
244 . " AND `table_name`=''";
245 $result = $this->dbi->tryQueryAsControlUser($sqlQuery);
247 $hidden = [];
248 if ($result) {
249 foreach ($result as $row) {
250 $type = $row['item_type'];
251 if (! isset($hidden[$type])) {
252 $hidden[$type] = [];
255 $hidden[$type][] = $row['item_name'];
259 return $hidden;
262 /** @return string Logo source */
263 private function getLogoSource(): string
265 /** @var ThemeManager $themeManager */
266 $themeManager = ContainerBuilder::getContainer()->get(ThemeManager::class);
267 $theme = $themeManager->theme;
269 if (@file_exists($theme->getFsPath() . 'img/logo_left.png')) {
270 return $theme->getPath() . '/img/logo_left.png';
273 if (@file_exists($theme->getFsPath() . 'img/pma_logo2.png')) {
274 return $theme->getPath() . '/img/pma_logo2.png';
277 return '';