#jpgraph
#pma
CKEditor_4.6.1
Date
backup
bibelpopup
classes
config
fetch_bibel
fetch_chorbuch
html2pdf-master
html2pdf_v4.03
images
jpgraph
kalender
language
lib
lieder
livesearch
msd
overlib
pma
doc
examples
js
libraries
cache
certs
classes
Charsets
Command
Config
Controllers
Database
Dbal
Display
Engines
Exceptions
Export
Gis
Html
Import
Navigation
Plugins
Properties
Providers
Query
Server
Setup
Table
Twig
Utils
Advisor.php
Bookmark.php
BrowseForeigners.php
Charsets.php
CheckUserPrivileges.php
Config.php
Console.php
Core.php
CreateAddField.php
DatabaseInterface.php
DbTableExists.php
Encoding.php
Error.php
ErrorHandler.php
ErrorReport.php
Export.php
File.php
FileListing.php
Font.php
Footer.php
Git.php
Header.php
Import.php
Index.php
IndexColumn.php
InsertEdit.php
InternalRelations.php
IpAllowDeny.php
Language.php
LanguageManager.php
Linter.php
ListAbstract.php
ListDatabase.php
Logging.php
Menu.php
Message.php
Mime.php
Normalization.php
OpenDocument.php
Operations.php
OutputBuffering.php
ParseAnalyze.php
Partition.php
Pdf.php
Plugins.php
Profiling.php
RecentFavoriteTable.php
Relation.php
RelationCleanup.php
Replication.php
ReplicationGui.php
ReplicationInfo.php
Response.php
Routing.php
Sanitize.php
SavedSearches.php
Scripts.php
Session.php
Sql.php
SqlQueryForm.php
StorageEngine.php
SubPartition.php
SystemDatabase.php
Table.php
TablePartitionDefinition.php
Template.php
Theme.php
ThemeManager.php
Tracker.php
Tracking.php
Transformations.php
TwoFactor.php
Types.php
Url.php
UserPassword.php
UserPreferences.php
Util.php
Version.php
VersionInformation.php
ZipExtension.php
advisory_rules_generic.php
advisory_rules_mysql_before80003.php
common.inc.php
config.default.php
config.values.php
language_stats.inc.php
routes.php
services.php
services_controllers.php
services_loader.php
vendor_config.php
locale
setup
sql
templates
themes
tmp
vendor
CONTRIBUTING.md
ChangeLog
LICENSE
README
RELEASE-DATE-5.1.1
babel.config.json
composer.json
composer.lock
config.inc.php
config.sample.inc.php
favicon.ico
index.php
package.json
print.css
robots.txt
show_config_errors.php
url.php
yarn.lock
templates
templates_c
test
validation
vendor
++ Umstellung Luther 2017.sql
.gitattributes
.htaccess
MyOOS-Dumper-master.zip
Version8_bugs.txt
ajax.js_20170928
ansicht.php
ansicht.php_20200212
ansicht.php_20200915
ansicht.php_lut84_20180219
ansicht2.php
ansicht2.php_20200212
ansicht2.php_20200915
ansicht2.php_lut84_20180219
ausgabe.php
bes_gd.php
bibellookup.php_lut84_20180219
bibellookup_1984.php
bibellookup_2017.php
bibellookup_2017.php_20200212
changelog.php
composer.json
composer.lock
config.inc.php
copy.js
faq_text.php
faq_text_ber.php
favicon.ico
fetch_data.php
ftp_ansicht.php
ftp_ansicht.php_20181214
func_agent.php
func_ansicht.php
func_ansicht.php_20200212
func_ansicht.php_20200915
func_ansicht.php_lut84_20180219
func_genUser.php
func_highlight.php
func_htmlclean.php
func_make_knk.php
func_make_knk_fa.php
func_make_knk_fa.php_lut84_20180219
func_make_reference_fa.php
func_make_reference_fa.php_lut84_20180219
func_rollenrechte.php
func_rollenrechte_20220202.php
func_write_lue_kat.php
further_publication.php
getSubCat.php
graph.php
graph_einzel.php
graph_hauptframe.php
graph_user.php
graph_user_hauptframe.php
hauptframe.php
hello.cgi
hello.pl
hilfe.php
historie.php
index.php
index2.php
indexframe.php
info.php
job_mail_delete_neue_user.php
job_mail_inaktiv.php
job_user_delete_neue_user.php
job_user_inaktiv.php
jquery.min.js
kat_cont.php
kat_cont.php_20201230
kat_cont.php_20221013
kat_cont_fa.php
kat_main.php
kat_main.php_lut84_20180219
kat_main_fa.php
kat_main_fa.php_lut84_20180219
katechismus.php
katechismus_fa.php
lesung.php
lieder.php
lieder.zip
livesearch.php
livestat.js
livestat.php
livestat2.php
login_log.php
logininfo.php
logout_admin.php
lue_ansicht.php
lue_bearbeiten.php
lue_erfassen.php
lue_inhalt.php
lue_inhalt.php_20200915
lue_inhalt.php_lut84_20180219
lue_notizen.php
lue_suche.php
lue_wahl.php
mail.php
make_ical.php
menuframe.php
nachsenden.php
notizen.php
outlook.php
outlook.php_20200212
outlook_ics.php
outlook_vcs.php
passwort_switch.php
pdf_gen.php
pdf_gen.php_20200915
pdf_gen.php_lut84_20180219
preview.php
profil.php
rollen.php
search_note.php
stichworte.php
suche.php
suche.php_20170928
suche_change.php
suche_simp.php
systemmail.php
test.php
test2.php
testmail.php
testmail2.php
topframe.php
upload.php
user_anlegen.php
user_bearbeiten.php
useronline.php
verweise.php
wort_bearbeiten.php
wort_bearbeiten.php_20170928
wort_erfassen.php
wort_erfassen.php_20170928
wort_exegese.php
wort_wahl.php
434 lines
12 KiB
PHP
434 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* Recent and Favorite table list handling
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace PhpMyAdmin;
|
|
|
|
use PhpMyAdmin\Html\Generator;
|
|
use const SORT_REGULAR;
|
|
use function array_key_exists;
|
|
use function array_merge;
|
|
use function array_pop;
|
|
use function array_unique;
|
|
use function array_unshift;
|
|
use function count;
|
|
use function htmlspecialchars;
|
|
use function json_decode;
|
|
use function json_encode;
|
|
use function max;
|
|
use function md5;
|
|
use function ucfirst;
|
|
|
|
/**
|
|
* Handles the recently used and favorite tables.
|
|
*
|
|
* @TODO Change the release version in table pma_recent
|
|
* (#recent in documentation)
|
|
*/
|
|
class RecentFavoriteTable
|
|
{
|
|
/**
|
|
* Reference to session variable containing recently used or favorite tables.
|
|
*
|
|
* @access private
|
|
* @var array
|
|
*/
|
|
private $tables;
|
|
|
|
/**
|
|
* Defines type of action, Favorite or Recent table.
|
|
*
|
|
* @access private
|
|
* @var string
|
|
*/
|
|
private $tableType;
|
|
|
|
/**
|
|
* RecentFavoriteTable instances.
|
|
*
|
|
* @access private
|
|
* @var array
|
|
*/
|
|
private static $instances = [];
|
|
|
|
/** @var Relation */
|
|
private $relation;
|
|
|
|
/**
|
|
* Creates a new instance of RecentFavoriteTable
|
|
*
|
|
* @param string $type the table type
|
|
*
|
|
* @access private
|
|
*/
|
|
private function __construct($type)
|
|
{
|
|
global $dbi;
|
|
|
|
$this->relation = new Relation($dbi);
|
|
$this->tableType = $type;
|
|
$server_id = $GLOBALS['server'];
|
|
if (! isset($_SESSION['tmpval'][$this->tableType . 'Tables'][$server_id])
|
|
) {
|
|
$_SESSION['tmpval'][$this->tableType . 'Tables'][$server_id]
|
|
= $this->getPmaTable() ? $this->getFromDb() : [];
|
|
}
|
|
$this->tables
|
|
=& $_SESSION['tmpval'][$this->tableType . 'Tables'][$server_id];
|
|
}
|
|
|
|
/**
|
|
* Returns class instance.
|
|
*
|
|
* @param string $type the table type
|
|
*
|
|
* @return RecentFavoriteTable
|
|
*/
|
|
public static function getInstance($type)
|
|
{
|
|
if (! array_key_exists($type, self::$instances)) {
|
|
self::$instances[$type] = new RecentFavoriteTable($type);
|
|
}
|
|
|
|
return self::$instances[$type];
|
|
}
|
|
|
|
/**
|
|
* Returns the recent/favorite tables array
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getTables()
|
|
{
|
|
return $this->tables;
|
|
}
|
|
|
|
/**
|
|
* Returns recently used tables or favorite from phpMyAdmin database.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getFromDb()
|
|
{
|
|
global $dbi;
|
|
|
|
// Read from phpMyAdmin database, if recent tables is not in session
|
|
$sql_query
|
|
= ' SELECT `tables` FROM ' . $this->getPmaTable() .
|
|
" WHERE `username` = '" . $dbi->escapeString($GLOBALS['cfg']['Server']['user']) . "'";
|
|
|
|
$return = [];
|
|
$result = $this->relation->queryAsControlUser($sql_query, false);
|
|
if ($result) {
|
|
$row = $dbi->fetchArray($result);
|
|
if (isset($row[0])) {
|
|
$return = json_decode($row[0], true);
|
|
}
|
|
}
|
|
|
|
return $return;
|
|
}
|
|
|
|
/**
|
|
* Save recent/favorite tables into phpMyAdmin database.
|
|
*
|
|
* @return true|Message
|
|
*/
|
|
public function saveToDb()
|
|
{
|
|
global $dbi;
|
|
|
|
$username = $GLOBALS['cfg']['Server']['user'];
|
|
$sql_query
|
|
= ' REPLACE INTO ' . $this->getPmaTable() . ' (`username`, `tables`)' .
|
|
" VALUES ('" . $dbi->escapeString($username) . "', '"
|
|
. $dbi->escapeString(
|
|
json_encode($this->tables)
|
|
) . "')";
|
|
|
|
$success = $dbi->tryQuery($sql_query, DatabaseInterface::CONNECT_CONTROL);
|
|
|
|
if (! $success) {
|
|
$error_msg = '';
|
|
switch ($this->tableType) {
|
|
case 'recent':
|
|
$error_msg = __('Could not save recent table!');
|
|
break;
|
|
|
|
case 'favorite':
|
|
$error_msg = __('Could not save favorite table!');
|
|
break;
|
|
}
|
|
$message = Message::error($error_msg);
|
|
$message->addMessage(
|
|
Message::rawError(
|
|
$dbi->getError(DatabaseInterface::CONNECT_CONTROL)
|
|
),
|
|
'<br><br>'
|
|
);
|
|
|
|
return $message;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Trim recent.favorite table according to the
|
|
* NumRecentTables/NumFavoriteTables configuration.
|
|
*
|
|
* @return bool True if trimming occurred
|
|
*/
|
|
public function trim()
|
|
{
|
|
$max = max(
|
|
$GLOBALS['cfg']['Num' . ucfirst($this->tableType) . 'Tables'],
|
|
0
|
|
);
|
|
$trimming_occurred = count($this->tables) > $max;
|
|
while (count($this->tables) > $max) {
|
|
array_pop($this->tables);
|
|
}
|
|
|
|
return $trimming_occurred;
|
|
}
|
|
|
|
/**
|
|
* Return HTML ul.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getHtmlList()
|
|
{
|
|
$html = '';
|
|
if (count($this->tables)) {
|
|
if ($this->tableType === 'recent') {
|
|
foreach ($this->tables as $table) {
|
|
$html .= '<li class="warp_link">';
|
|
$recent_url = Url::getFromRoute('/table/recent-favorite', [
|
|
'db' => $table['db'],
|
|
'table' => $table['table'],
|
|
]);
|
|
$html .= '<a href="' . $recent_url . '">`'
|
|
. htmlspecialchars($table['db']) . '`.`'
|
|
. htmlspecialchars($table['table']) . '`</a>';
|
|
$html .= '</li>';
|
|
}
|
|
} else {
|
|
foreach ($this->tables as $table) {
|
|
$html .= '<li class="warp_link">';
|
|
|
|
$html .= '<a class="ajax favorite_table_anchor" ';
|
|
$fav_rm_url = Url::getFromRoute('/database/structure/favorite-table', [
|
|
'db' => $table['db'],
|
|
'ajax_request' => true,
|
|
'favorite_table' => $table['table'],
|
|
'remove_favorite' => true,
|
|
]);
|
|
$html .= 'href="' . $fav_rm_url
|
|
. '" title="' . __('Remove from Favorites')
|
|
. '" data-favtargetn="'
|
|
. md5($table['db'] . '.' . $table['table'])
|
|
. '" >'
|
|
. Generator::getIcon('b_favorite')
|
|
. '</a>';
|
|
|
|
$table_url = Url::getFromRoute('/table/recent-favorite', [
|
|
'db' => $table['db'],
|
|
'table' => $table['table'],
|
|
]);
|
|
$html .= '<a href="' . $table_url . '">`'
|
|
. htmlspecialchars($table['db']) . '`.`'
|
|
. htmlspecialchars($table['table']) . '`</a>';
|
|
$html .= '</li>';
|
|
}
|
|
}
|
|
} else {
|
|
$html .= '<li class="warp_link">'
|
|
. ($this->tableType === 'recent'
|
|
? __('There are no recent tables.')
|
|
: __('There are no favorite tables.'))
|
|
. '</li>';
|
|
}
|
|
|
|
return $html;
|
|
}
|
|
|
|
/**
|
|
* Return HTML.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getHtml()
|
|
{
|
|
$html = '<div class="drop_list">';
|
|
if ($this->tableType === 'recent') {
|
|
$html .= '<button title="' . __('Recent tables')
|
|
. '" class="drop_button btn">'
|
|
. __('Recent') . '</button><ul id="pma_recent_list">';
|
|
} else {
|
|
$html .= '<button title="' . __('Favorite tables')
|
|
. '" class="drop_button btn">'
|
|
. __('Favorites') . '</button><ul id="pma_favorite_list">';
|
|
}
|
|
$html .= $this->getHtmlList();
|
|
$html .= '</ul></div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
/**
|
|
* Add recently used or favorite tables.
|
|
*
|
|
* @param string $db database name where the table is located
|
|
* @param string $table table name
|
|
*
|
|
* @return true|Message True if success, Message if not
|
|
*/
|
|
public function add($db, $table)
|
|
{
|
|
global $dbi;
|
|
|
|
// If table does not exist, do not add._getPmaTable()
|
|
if (! $dbi->getColumns($db, $table)) {
|
|
return true;
|
|
}
|
|
|
|
$table_arr = [];
|
|
$table_arr['db'] = $db;
|
|
$table_arr['table'] = $table;
|
|
|
|
// add only if this is new table
|
|
if (! isset($this->tables[0]) || $this->tables[0] != $table_arr) {
|
|
array_unshift($this->tables, $table_arr);
|
|
$this->tables = array_merge(array_unique($this->tables, SORT_REGULAR));
|
|
$this->trim();
|
|
if ($this->getPmaTable()) {
|
|
return $this->saveToDb();
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Removes recent/favorite tables that don't exist.
|
|
*
|
|
* @param string $db database
|
|
* @param string $table table
|
|
*
|
|
* @return bool|Message True if invalid and removed, False if not invalid,
|
|
* Message if error while removing
|
|
*/
|
|
public function removeIfInvalid($db, $table)
|
|
{
|
|
global $dbi;
|
|
|
|
foreach ($this->tables as $tbl) {
|
|
if ($tbl['db'] != $db || $tbl['table'] != $table) {
|
|
continue;
|
|
}
|
|
|
|
// TODO Figure out a better way to find the existence of a table
|
|
if (! $dbi->getColumns($tbl['db'], $tbl['table'])) {
|
|
return $this->remove($tbl['db'], $tbl['table']);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Remove favorite tables.
|
|
*
|
|
* @param string $db database name where the table is located
|
|
* @param string $table table name
|
|
*
|
|
* @return true|Message True if success, Message if not
|
|
*/
|
|
public function remove($db, $table)
|
|
{
|
|
foreach ($this->tables as $key => $value) {
|
|
if ($value['db'] != $db || $value['table'] != $table) {
|
|
continue;
|
|
}
|
|
|
|
unset($this->tables[$key]);
|
|
}
|
|
if ($this->getPmaTable()) {
|
|
return $this->saveToDb();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Generate Html for sync Favorite tables anchor. (from localStorage to pmadb)
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getHtmlSyncFavoriteTables()
|
|
{
|
|
$retval = '';
|
|
$server_id = $GLOBALS['server'];
|
|
if ($server_id == 0) {
|
|
return '';
|
|
}
|
|
$cfgRelation = $this->relation->getRelationsParam();
|
|
// Not to show this once list is synchronized.
|
|
if ($cfgRelation['favoritework'] && ! isset($_SESSION['tmpval']['favorites_synced'][$server_id])) {
|
|
$url = Url::getFromRoute('/database/structure/favorite-table', [
|
|
'ajax_request' => true,
|
|
'favorite_table' => true,
|
|
'sync_favorite_tables' => true,
|
|
]);
|
|
$retval = '<a class="hide" id="sync_favorite_tables"';
|
|
$retval .= ' href="' . $url . '"></a>';
|
|
}
|
|
|
|
return $retval;
|
|
}
|
|
|
|
/**
|
|
* Generate Html to update recent tables.
|
|
*
|
|
* @return string html
|
|
*/
|
|
public static function getHtmlUpdateRecentTables()
|
|
{
|
|
$retval = '<a class="hide" id="update_recent_tables" href="';
|
|
$retval .= Url::getFromRoute('/recent-table', [
|
|
'ajax_request' => true,
|
|
'recent_table' => true,
|
|
]);
|
|
$retval .= '"></a>';
|
|
|
|
return $retval;
|
|
}
|
|
|
|
/**
|
|
* Return the name of the configuration storage table
|
|
*
|
|
* @return string|null pma table name
|
|
*/
|
|
private function getPmaTable(): ?string
|
|
{
|
|
$cfgRelation = $this->relation->getRelationsParam();
|
|
if (! $cfgRelation['recentwork']) {
|
|
return null;
|
|
}
|
|
|
|
if (! empty($cfgRelation['db'])
|
|
&& ! empty($cfgRelation[$this->tableType])
|
|
) {
|
|
return Util::backquote($cfgRelation['db']) . '.'
|
|
. Util::backquote($cfgRelation[$this->tableType]);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|