Translated using Weblate (Estonian)
[phpmyadmin.git] / libraries / classes / RecentFavoriteTable.php
blob194939ce626f2d9aca97afc1a9529498682df637
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Recent and Favorite table list handling
6 * @package PhpMyAdmin
7 */
8 declare(strict_types=1);
10 namespace PhpMyAdmin;
12 /**
13 * Handles the recently used and favorite tables.
15 * @TODO Change the release version in table pma_recent
16 * (#recent in documentation)
18 * @package PhpMyAdmin
20 class RecentFavoriteTable
22 /**
23 * Reference to session variable containing recently used or favorite tables.
25 * @access private
26 * @var array
28 private $_tables;
30 /**
31 * Defines type of action, Favorite or Recent table.
33 * @access private
34 * @var string
36 private $_tableType;
38 /**
39 * RecentFavoriteTable instances.
41 * @access private
42 * @var array
44 private static $_instances = [];
46 /**
47 * @var Relation
49 private $relation;
51 /**
52 * Creates a new instance of RecentFavoriteTable
54 * @param string $type the table type
56 * @access private
58 private function __construct($type)
60 $this->relation = new Relation($GLOBALS['dbi']);
61 $this->_tableType = $type;
62 $server_id = $GLOBALS['server'];
63 if (! isset($_SESSION['tmpval'][$this->_tableType . 'Tables'][$server_id])
64 ) {
65 $_SESSION['tmpval'][$this->_tableType . 'Tables'][$server_id]
66 = $this->_getPmaTable() ? $this->getFromDb() : [];
68 $this->_tables
69 =& $_SESSION['tmpval'][$this->_tableType . 'Tables'][$server_id];
72 /**
73 * Returns class instance.
75 * @param string $type the table type
77 * @return RecentFavoriteTable
79 public static function getInstance($type)
81 if (! array_key_exists($type, self::$_instances)) {
82 self::$_instances[$type] = new RecentFavoriteTable($type);
84 return self::$_instances[$type];
87 /**
88 * Returns the recent/favorite tables array
90 * @return array
92 public function getTables()
94 return $this->_tables;
97 /**
98 * Returns recently used tables or favorite from phpMyAdmin database.
100 * @return array
102 public function getFromDb()
104 // Read from phpMyAdmin database, if recent tables is not in session
105 $sql_query
106 = " SELECT `tables` FROM " . $this->_getPmaTable() .
107 " WHERE `username` = '" . $GLOBALS['dbi']->escapeString($GLOBALS['cfg']['Server']['user']) . "'";
109 $return = [];
110 $result = $this->relation->queryAsControlUser($sql_query, false);
111 if ($result) {
112 $row = $GLOBALS['dbi']->fetchArray($result);
113 if (isset($row[0])) {
114 $return = json_decode($row[0], true);
117 return $return;
121 * Save recent/favorite tables into phpMyAdmin database.
123 * @return true|Message
125 public function saveToDb()
127 $username = $GLOBALS['cfg']['Server']['user'];
128 $sql_query
129 = " REPLACE INTO " . $this->_getPmaTable() . " (`username`, `tables`)" .
130 " VALUES ('" . $GLOBALS['dbi']->escapeString($username) . "', '"
131 . $GLOBALS['dbi']->escapeString(
132 json_encode($this->_tables)
133 ) . "')";
135 $success = $GLOBALS['dbi']->tryQuery($sql_query, DatabaseInterface::CONNECT_CONTROL);
137 if (! $success) {
138 $error_msg = '';
139 switch ($this->_tableType) {
140 case 'recent':
141 $error_msg = __('Could not save recent table!');
142 break;
144 case 'favorite':
145 $error_msg = __('Could not save favorite table!');
146 break;
148 $message = Message::error($error_msg);
149 $message->addMessage(
150 Message::rawError(
151 $GLOBALS['dbi']->getError(DatabaseInterface::CONNECT_CONTROL)
153 '<br><br>'
155 return $message;
157 return true;
161 * Trim recent.favorite table according to the
162 * NumRecentTables/NumFavoriteTables configuration.
164 * @return boolean True if trimming occurred
166 public function trim()
168 $max = max(
169 $GLOBALS['cfg']['Num' . ucfirst($this->_tableType) . 'Tables'],
172 $trimming_occurred = count($this->_tables) > $max;
173 while (count($this->_tables) > $max) {
174 array_pop($this->_tables);
176 return $trimming_occurred;
180 * Return HTML ul.
182 * @return string
184 public function getHtmlList()
186 $html = '';
187 if (count($this->_tables)) {
188 if ($this->_tableType == 'recent') {
189 foreach ($this->_tables as $table) {
190 $html .= '<li class="warp_link">';
191 $recent_params = [
192 'db' => $table['db'],
193 'table' => $table['table'],
195 $recent_url = 'tbl_recent_favorite.php'
196 . Url::getCommon($recent_params);
197 $html .= '<a href="' . $recent_url . '">`'
198 . htmlspecialchars($table['db']) . '`.`'
199 . htmlspecialchars($table['table']) . '`</a>';
200 $html .= '</li>';
202 } else {
203 foreach ($this->_tables as $table) {
204 $html .= '<li class="warp_link">';
206 $html .= '<a class="ajax favorite_table_anchor" ';
207 $fav_rm_url = Url::getFromRoute('/database/structure', [
208 'db' => $table['db'],
209 'ajax_request' => true,
210 'favorite_table' => $table['table'],
211 'remove_favorite' => true,
213 $html .= 'href="' . $fav_rm_url
214 . '" title="' . __("Remove from Favorites")
215 . '" data-favtargetn="'
216 . md5($table['db'] . "." . $table['table'])
217 . '" >'
218 . Util::getIcon('b_favorite')
219 . '</a>';
221 $fav_params = [
222 'db' => $table['db'],
223 'table' => $table['table'],
225 $table_url = 'tbl_recent_favorite.php'
226 . Url::getCommon($fav_params);
227 $html .= '<a href="' . $table_url . '">`'
228 . htmlspecialchars($table['db']) . '`.`'
229 . htmlspecialchars($table['table']) . '`</a>';
230 $html .= '</li>';
233 } else {
234 $html .= '<li class="warp_link">'
235 . ($this->_tableType == 'recent'
236 ? __('There are no recent tables.')
237 : __('There are no favorite tables.'))
238 . '</li>';
240 return $html;
244 * Return HTML.
246 * @return string
248 public function getHtml()
250 $html = '<div class="drop_list">';
251 if ($this->_tableType == 'recent') {
252 $html .= '<button title="' . __('Recent tables')
253 . '" class="drop_button btn">'
254 . __('Recent') . '</button><ul id="pma_recent_list">';
255 } else {
256 $html .= '<button title="' . __('Favorite tables')
257 . '" class="drop_button btn">'
258 . __('Favorites') . '</button><ul id="pma_favorite_list">';
260 $html .= $this->getHtmlList();
261 $html .= '</ul></div>';
262 return $html;
266 * Add recently used or favorite tables.
268 * @param string $db database name where the table is located
269 * @param string $table table name
271 * @return true|Message True if success, Message if not
273 public function add($db, $table)
275 // If table does not exist, do not add._getPmaTable()
276 if (! $GLOBALS['dbi']->getColumns($db, $table)) {
277 return true;
280 $table_arr = [];
281 $table_arr['db'] = $db;
282 $table_arr['table'] = $table;
284 // add only if this is new table
285 if (! isset($this->_tables[0]) || $this->_tables[0] != $table_arr) {
286 array_unshift($this->_tables, $table_arr);
287 $this->_tables = array_merge(array_unique($this->_tables, SORT_REGULAR));
288 $this->trim();
289 if ($this->_getPmaTable()) {
290 return $this->saveToDb();
293 return true;
297 * Removes recent/favorite tables that don't exist.
299 * @param string $db database
300 * @param string $table table
302 * @return boolean|Message True if invalid and removed, False if not invalid,
303 * Message if error while removing
305 public function removeIfInvalid($db, $table)
307 foreach ($this->_tables as $tbl) {
308 if ($tbl['db'] == $db && $tbl['table'] == $table) {
309 // TODO Figure out a better way to find the existence of a table
310 if (! $GLOBALS['dbi']->getColumns($tbl['db'], $tbl['table'])) {
311 return $this->remove($tbl['db'], $tbl['table']);
315 return false;
319 * Remove favorite tables.
321 * @param string $db database name where the table is located
322 * @param string $table table name
324 * @return true|Message True if success, Message if not
326 public function remove($db, $table)
328 foreach ($this->_tables as $key => $value) {
329 if ($value['db'] == $db && $value['table'] == $table) {
330 unset($this->_tables[$key]);
333 if ($this->_getPmaTable()) {
334 return $this->saveToDb();
336 return true;
340 * Generate Html for sync Favorite tables anchor. (from localStorage to pmadb)
342 * @return string
344 public function getHtmlSyncFavoriteTables()
346 $retval = '';
347 $server_id = $GLOBALS['server'];
348 if ($server_id == 0) {
349 return '';
351 $cfgRelation = $this->relation->getRelationsParam();
352 // Not to show this once list is synchronized.
353 if ($cfgRelation['favoritework'] && ! isset($_SESSION['tmpval']['favorites_synced'][$server_id])) {
354 $url = Url::getFromRoute('/database/structure', [
355 'ajax_request' => true,
356 'favorite_table' => true,
357 'sync_favorite_tables' => true,
359 $retval = '<a class="hide" id="sync_favorite_tables"';
360 $retval .= ' href="' . $url . '"></a>';
362 return $retval;
366 * Generate Html to update recent tables.
368 * @return string html
370 public static function getHtmlUpdateRecentTables()
372 $params = [
373 'ajax_request' => true,
374 'recent_table' => true,
376 $url = 'index.php' . Url::getCommon($params);
377 $retval = '<a class="hide" id="update_recent_tables"';
378 $retval .= ' href="' . $url . '"></a>';
379 return $retval;
383 * Return the name of the configuration storage table
385 * @return string|null pma table name
387 private function _getPmaTable(): ?string
389 $cfgRelation = $this->relation->getRelationsParam();
390 if (! empty($cfgRelation['db'])
391 && ! empty($cfgRelation[$this->_tableType])
393 return Util::backquote($cfgRelation['db']) . "."
394 . Util::backquote($cfgRelation[$this->_tableType]);
396 return null;