Merge pull request #1115 from ashutoshdhundhara/favorite_table

Favorite tables feature using Ajax.
This commit is contained in:
Marc Delisle 2014-03-28 14:47:55 -04:00
commit 0e13fc74a2
10 changed files with 221 additions and 306 deletions

View File

@ -16,6 +16,61 @@ require_once 'libraries/common.inc.php';
*/
require_once 'libraries/structure.lib.php';
// Add/Remove favorite tables using Ajax request.
if ($GLOBALS['is_ajax_request'] && ! empty($_REQUEST['favorite_table'])) {
global $db;
$changes = true;
$msg = '';
$titles = PMA_Util::buildActionTitles();
$fav_instance = PMA_RecentFavoriteTable::getInstance('favorite');
$favorite_table = $_REQUEST['favorite_table'];
$already_favorite = PMA_checkFavoriteTable($db, $favorite_table);
if (isset($_REQUEST['remove_favorite'])) {
if ($already_favorite) {
// If already in favorite list, remove it.
$fav_instance->remove($db, $favorite_table);
}
} elseif (isset($_REQUEST['add_favorite'])) {
if (!$already_favorite) {
if (count($fav_instance->tables) == $GLOBALS['cfg']['NumFavoriteTables']) {
$changes = false;
$msg = '<div class="error"><img src="themes/dot.gif" '
. 'title="" alt="" class="icon ic_s_error" />'
. __("Favorite List is full!")
. '</div>';
} else {
// Otherwise add to favorite list.
$fav_instance->add($db, $favorite_table);
}
}
} else {
}
$ajax_response = PMA_Response::getInstance();
$ajax_response->addJSON(
'changes',
$changes
);
if ($changes) {
$ajax_response->addJSON(
'options',
PMA_RecentFavoriteTable::getInstance('favorite')->getHtmlSelectOption()
);
$ajax_response->addJSON(
'anchor',
PMA_getHtmlForFavoriteAnchor($db, array('TABLE_NAME' => $favorite_table), $titles)
);
} else {
$ajax_response->addJSON(
'message',
$msg
);
}
exit;
}
$response = PMA_Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
@ -133,8 +188,8 @@ $overhead_size = (double) 0;
$hidden_fields = array();
$odd_row = true;
$sum_row_count_pre = '';
// Instance of PMA_FavoriteTable class.
$fav_instance = PMA_FavoriteTable::getInstance();
// Instance of PMA_RecentFavoriteTable class.
$fav_instance = PMA_RecentFavoriteTable::getInstance('favorite');
foreach ($tables as $keyname => $current_table) {
// Get valid statistics whatever is the table type

View File

@ -1920,6 +1920,28 @@ next to the column name, when the tooltip tells you to do so. This
will show you an input box with the column name. You may right-click
the column name within this input box to copy it to your clipboard.
.. _faq6_34:
6.34 How can I use the Favorite Tables feature?
---------------------------------------------------------
Favorite Tables feature is very much similar to Recent Tables feature.
It allows you to add a shortcut for the frequently used tables of any
database in the navigation panel . You can easily navigate to any table
in the list by simply choosing it from the list. These tables are stored
temporarily in your session if you have not configured your
`phpMyAdmin Configuration Storage`. Otherwise these entries are permanent.
To add a table to Favorite list simply click on the `Gray` star in front
of a table name in the list of tables of a Database and wait until it
turns to `Yellow`.
To remove a table from list, simply click on the `Yellow` star and
wait until it turns `Gray` again.
Using :config:option:`$cfg['NumFavoriteTables']` in your :file:`config.inc.php`
file, you can define the maximum number of favorite tables shown in the
navigation panel. Its default value is `10`.
.. _faqproject:
phpMyAdmin project

View File

@ -56,12 +56,12 @@ if (! empty($_REQUEST['target'])
/**
* Check if it is an ajax request to reload the recent tables list.
*/
require_once 'libraries/RecentTable.class.php';
require_once 'libraries/RecentFavoriteTable.class.php';
if ($GLOBALS['is_ajax_request'] && ! empty($_REQUEST['recent_table'])) {
$response = PMA_Response::getInstance();
$response->addJSON(
'options',
PMA_RecentTable::getInstance()->getHtmlSelectOption()
PMA_RecentFavoriteTable::getInstance('recent')->getHtmlSelectOption()
);
exit;
}

View File

@ -28,6 +28,7 @@ AJAX.registerTeardown('db_structure.js', function () {
$("a.drop_table_anchor.ajax").die('click');
$('a.drop_tracking_anchor.ajax').die('click');
$('#real_end_input').die('click');
$("a.favorite_table_anchor.ajax").die('click');
});
/**
@ -396,4 +397,30 @@ AJAX.registerOnload('db_structure.js', function () {
);
});
// Add/Remove favorite table using Ajax.
$(".favorite_table_anchor").live("click", function (event) {
event.preventDefault();
var anchor_id = $(this).attr("id");
$.get(
$(this).attr('href'),
function (data) {
if (data.success === true) {
if (data.changes) {
$('#favoriteTable').html(data.options);
$('#' + anchor_id).parent().html(data.anchor);
PMA_tooltip(
$('#' + anchor_id),
'a',
$('#' + anchor_id).attr("title")
);
} else {
PMA_ajaxShowMessage(data.message);
}
} else {
PMA_ajaxShowMessage(data.message);
}
}
);
});
}); // end $()

View File

@ -10,8 +10,7 @@ if (! defined('PHPMYADMIN')) {
}
require_once 'libraries/Scripts.class.php';
require_once 'libraries/RecentTable.class.php';
require_once 'libraries/FavoriteTable.class.php';
require_once 'libraries/RecentFavoriteTable.class.php';
require_once 'libraries/Menu.class.php';
require_once 'libraries/navigation/Navigation.class.php';
require_once 'libraries/url_generating.lib.php';
@ -703,7 +702,7 @@ class PMA_Header
&& strlen($table)
&& $GLOBALS['cfg']['NumRecentTables'] > 0
) {
$tmp_result = PMA_RecentTable::getInstance()->add($db, $table);
$tmp_result = PMA_RecentFavoriteTable::getInstance('recent')->add($db, $table);
if ($tmp_result === true) {
$params = array('ajax_request' => true, 'recent_table' => true);
$url = 'index.php' . PMA_URL_getCommon($params);

View File

@ -1,7 +1,7 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Favorite table list handling
* Recent and Favorite table list handling
*
* @package PhpMyAdmin
*/
@ -13,15 +13,17 @@ if (! defined('PHPMYADMIN')) {
require_once './libraries/Message.class.php';
/**
* Handles the favorite tables list.
* Handles the recently used and favorite tables.
*
* @TODO Change the release version in table pma_recent
* (#recent in documentation)
*
* @package PhpMyAdmin
*/
class PMA_FavoriteTable
class PMA_RecentFavoriteTable
{
/**
* Defines the internal PMA table which contains favorite tables.
* Defines the internal PMA table which contains recent/favorite tables.
*
* @access private
* @var string
@ -29,7 +31,7 @@ class PMA_FavoriteTable
private $_pmaTable;
/**
* Reference to session variable containing favorite used tables.
* Reference to session variable containing recently used or favorite tables.
*
* @access public
* @var array
@ -37,53 +39,66 @@ class PMA_FavoriteTable
public $tables;
/**
* PMA_FavoriteTable instance.
* Defines type of action, Favorite or Recent table.
*
* @var PMA_FavoriteTable
* @access public
* @var string
*/
public $table_type;
/**
* PMA_RecentFavoriteTable instance.
*
* @var PMA_RecentFavoriteTable
*/
private static $_instance;
/**
* Creates a new instance of PMA_FavoriteTable
* Creates a new instance of PMA_RecentFavoriteTable
*/
public function __construct()
public function __construct($type)
{
$this->table_type = $type;
if (strlen($GLOBALS['cfg']['Server']['pmadb'])
&& strlen($GLOBALS['cfg']['Server']['favorite'])
&& strlen($GLOBALS['cfg']['Server'][$this->table_type])
) {
$this->_pmaTable
= PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "."
. PMA_Util::backquote($GLOBALS['cfg']['Server']['favorite']);
. PMA_Util::backquote($GLOBALS['cfg']['Server'][$this->table_type]);
}
$server_id = $GLOBALS['server'];
if (! isset($_SESSION['tmpval']['favorite_tables'][$server_id])) {
$_SESSION['tmpval']['favorite_tables'][$server_id]
if (! isset($_SESSION['tmpval'][$this->table_type . '_tables'][$server_id])) {
$_SESSION['tmpval'][$this->table_type . '_tables'][$server_id]
= isset($this->_pmaTable) ? $this->getFromDb() : array();
}
$this->tables =& $_SESSION['tmpval']['favorite_tables'][$server_id];
$this->tables =& $_SESSION['tmpval'][$this->table_type . '_tables'][$server_id];
}
/**
* Returns class instance.
*
* @return PMA_FavoriteTable
* @return PMA_RecentFavoriteTable
*/
public static function getInstance()
public static function getInstance($type)
{
if (is_null(self::$_instance)) {
self::$_instance = new PMA_FavoriteTable();
self::$_instance = new PMA_RecentFavoriteTable($type);
} else {
if (self::$_instance->table_type != $type) {
self::$_instance = new PMA_RecentFavoriteTable($type);
}
}
return self::$_instance;
}
/**
* Returns favorite tables from phpMyAdmin database.
* Returns recently used tables or favorite from phpMyAdmin database.
*
* @return array
*/
public function getFromDb()
{
// Read from phpMyAdmin database, if favorite tables are not in session
// Read from phpMyAdmin database, if recent tables is not in session
$sql_query
= " SELECT `tables` FROM " . $this->_pmaTable .
" WHERE `username` = '" . $GLOBALS['cfg']['Server']['user'] . "'";
@ -100,7 +115,7 @@ class PMA_FavoriteTable
}
/**
* Save favorite tables into phpMyAdmin database.
* Save recent/favorite tables into phpMyAdmin database.
*
* @return true|PMA_Message
*/
@ -117,7 +132,17 @@ class PMA_FavoriteTable
$success = $GLOBALS['dbi']->tryQuery($sql_query, $GLOBALS['controllink']);
if (! $success) {
$message = PMA_Message::error(__('Could not save favorite table!'));
$error_msg = '';
switch ($this->table_type) {
case 'recent':
$error_msg = __('Could not save recent table!');
break;
case 'favorite':
$error_msg = __('Could not save favorite table!');
break;
}
$message = PMA_Message::error($error_msg);
$message->addMessage('<br /><br />');
$message->addMessage(
PMA_Message::rawError(
@ -130,43 +155,13 @@ class PMA_FavoriteTable
}
/**
* Remove favorite tables from phpMyAdmin database.
*
* @return true|PMA_Message
*/
public function removeFromDb()
{
$username = $GLOBALS['cfg']['Server']['user'];
$sql_query
= " REPLACE INTO " . $this->_pmaTable . " (`username`, `tables`)" .
" VALUES ('" . $username . "', '"
. PMA_Util::sqlAddSlashes(
json_encode($this->tables)
) . "')";
$success = $GLOBALS['dbi']->tryQuery($sql_query, $GLOBALS['controllink']);
if (! $success) {
$message = PMA_Message::error(__('Could not remove favorite table!'));
$message->addMessage('<br /><br />');
$message->addMessage(
PMA_Message::rawError(
$GLOBALS['dbi']->getError($GLOBALS['controllink'])
)
);
return $message;
}
return true;
}
/**
* Trim favorite table according to the NumFavoriteTables configuration.
* Trim recent.favorite table according to the NumRecentTables/NumFavoriteTables configuration.
*
* @return boolean True if trimming occurred
*/
public function trim()
{
$max = max($GLOBALS['cfg']['NumFavoriteTables'], 0);
$max = max($GLOBALS['cfg']['Num' . ucfirst($this->table_type) . 'Tables'], 0);
$trimming_occurred = count($this->tables) > $max;
while (count($this->tables) > $max) {
array_pop($this->tables);
@ -186,7 +181,20 @@ class PMA_FavoriteTable
$this->saveToDb();
}
$html = '<option value="">(' . __('Favorite tables') . ') ...</option>';
$first_option = '';
$last_option = '';
switch ($this->table_type) {
case 'recent':
$first_option = __("Recent tables");
$last_option = __("There are no recent tables.");
break;
case 'favorite':
$first_option = __("Favorite tables");
$last_option = __("There are no favorite tables.");
break;
}
$html = '<option value="">(' . $first_option . ') ...</option>';
if (count($this->tables)) {
foreach ($this->tables as $table) {
$html .= '<option value="'
@ -198,7 +206,7 @@ class PMA_FavoriteTable
}
} else {
$html .= '<option value="">'
. __('There are no favorite tables.')
. $last_option
. '</option>';
}
return $html;
@ -211,7 +219,7 @@ class PMA_FavoriteTable
*/
public function getHtmlSelect()
{
$html = '<select name="selected_favorite_table" id="favoriteTable">';
$html = '<select name="selected_' . $this->table_type . '_table" id="' . $this->table_type . 'Table">';
$html .= $this->getHtmlSelectOption();
$html .= '</select>';
@ -219,7 +227,7 @@ class PMA_FavoriteTable
}
/**
* Add favorite tables.
* Add recently used or favorite tables.
*
* @param string $db database name where the table is located
* @param string $table table name
@ -263,7 +271,7 @@ class PMA_FavoriteTable
}
}
if (isset($this->_pmaTable)) {
return $this->removeFromDb();
return $this->saveToDb();
}
return true;
}

View File

@ -1,220 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Recent table list handling
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
require_once './libraries/Message.class.php';
/**
* Handles the recently used tables.
*
* @TODO Change the release version in table pma_recent
* (#recent in documentation)
*
* @package PhpMyAdmin
*/
class PMA_RecentTable
{
/**
* Defines the internal PMA table which contains recent tables.
*
* @access private
* @var string
*/
private $_pmaTable;
/**
* Reference to session variable containing recently used tables.
*
* @access public
* @var array
*/
public $tables;
/**
* PMA_RecentTable instance.
*
* @var PMA_RecentTable
*/
private static $_instance;
/**
* Creates a new instance of PMA_RecentTable
*/
public function __construct()
{
if (strlen($GLOBALS['cfg']['Server']['pmadb'])
&& strlen($GLOBALS['cfg']['Server']['recent'])
) {
$this->_pmaTable
= PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "."
. PMA_Util::backquote($GLOBALS['cfg']['Server']['recent']);
}
$server_id = $GLOBALS['server'];
if (! isset($_SESSION['tmpval']['recent_tables'][$server_id])) {
$_SESSION['tmpval']['recent_tables'][$server_id]
= isset($this->_pmaTable) ? $this->getFromDb() : array();
}
$this->tables =& $_SESSION['tmpval']['recent_tables'][$server_id];
}
/**
* Returns class instance.
*
* @return PMA_RecentTable
*/
public static function getInstance()
{
if (is_null(self::$_instance)) {
self::$_instance = new PMA_RecentTable();
}
return self::$_instance;
}
/**
* Returns recently used tables from phpMyAdmin database.
*
* @return array
*/
public function getFromDb()
{
// Read from phpMyAdmin database, if recent tables is not in session
$sql_query
= " SELECT `tables` FROM " . $this->_pmaTable .
" WHERE `username` = '" . $GLOBALS['cfg']['Server']['user'] . "'";
$return = array();
$result = PMA_queryAsControlUser($sql_query, false);
if ($result) {
$row = $GLOBALS['dbi']->fetchArray($result);
if (isset($row[0])) {
$return = json_decode($row[0], true);
}
}
return $return;
}
/**
* Save recent tables into phpMyAdmin database.
*
* @return true|PMA_Message
*/
public function saveToDb()
{
$username = $GLOBALS['cfg']['Server']['user'];
$sql_query
= " REPLACE INTO " . $this->_pmaTable . " (`username`, `tables`)" .
" VALUES ('" . $username . "', '"
. PMA_Util::sqlAddSlashes(
json_encode($this->tables)
) . "')";
$success = $GLOBALS['dbi']->tryQuery($sql_query, $GLOBALS['controllink']);
if (! $success) {
$message = PMA_Message::error(__('Could not save recent table!'));
$message->addMessage('<br /><br />');
$message->addMessage(
PMA_Message::rawError(
$GLOBALS['dbi']->getError($GLOBALS['controllink'])
)
);
return $message;
}
return true;
}
/**
* Trim recent table according to the NumRecentTables configuration.
*
* @return boolean True if trimming occurred
*/
public function trim()
{
$max = max($GLOBALS['cfg']['NumRecentTables'], 0);
$trimming_occurred = count($this->tables) > $max;
while (count($this->tables) > $max) {
array_pop($this->tables);
}
return $trimming_occurred;
}
/**
* Return options for HTML select.
*
* @return string
*/
public function getHtmlSelectOption()
{
// trim and save, in case where the configuration is changed
if ($this->trim() && isset($this->_pmaTable)) {
$this->saveToDb();
}
$html = '<option value="">(' . __('Recent tables') . ') ...</option>';
if (count($this->tables)) {
foreach ($this->tables as $table) {
$html .= '<option value="'
. htmlspecialchars(json_encode($table)) . '">'
. htmlspecialchars(
'`' . $table['db'] . '`.`' . $table['table'] . '`'
)
. '</option>';
}
} else {
$html .= '<option value="">'
. __('There are no recent tables.')
. '</option>';
}
return $html;
}
/**
* Return HTML select.
*
* @return string
*/
public function getHtmlSelect()
{
$html = '<select name="selected_recent_table" id="recentTable">';
$html .= $this->getHtmlSelectOption();
$html .= '</select>';
return $html;
}
/**
* Add recently used tables.
*
* @param string $db database name where the table is located
* @param string $table table name
*
* @return true|PMA_Message True if success, PMA_Message if not
*/
public function add($db, $table)
{
$table_arr = array();
$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 (isset($this->_pmaTable)) {
return $this->saveToDb();
}
}
return true;
}
}
?>

View File

@ -474,6 +474,7 @@ $strConfigNumRecentTables_desc
$strConfigNumFavoriteTables_desc
= __('Maximum number of favorite tables; set 0 to disable.');
$strConfigNumRecentTables_name = __('Recently used tables');
$strConfigNumFavoriteTables_name = __('Favorite tables');
$strConfigRowActionLinks_desc = __('These are Edit, Copy and Delete links.');
$strConfigRowActionLinks_name = __('Where to show the table row links');
$strConfigNaturalOrder_desc

View File

@ -289,8 +289,8 @@ class PMA_NavigationHeader
private function _recent()
{
$retval = '';
// display recently used tables
if ($GLOBALS['cfg']['NumRecentTables'] > 0) {
// display recently used or favorite tables
if ($GLOBALS['cfg']['NumRecentTables'] > 0 || $GLOBALS['cfg']['NumFavoriteTables'] > 0) {
$retval .= '<!-- RECENT START -->';
$retval .= '<div id="recentTableList">';
$retval .= '<form method="post" ';
@ -302,8 +302,12 @@ class PMA_NavigationHeader
'server' => $GLOBALS['server']
)
);
$retval .= PMA_RecentTable::getInstance()->getHtmlSelect();
$retval .= $this->_favorite();
if ($GLOBALS['cfg']['NumRecentTables'] > 0) {
$retval .= PMA_RecentFavoriteTable::getInstance('recent')->getHtmlSelect();
}
if ($GLOBALS['cfg']['NumFavoriteTables'] > 0) {
$retval .= $this->_favorite();
}
$retval .= '</form>';
$retval .= '</div>';
$retval .= '<!-- RECENT END -->';
@ -321,7 +325,7 @@ class PMA_NavigationHeader
$retval = '';
// display favorite tables
if ($GLOBALS['cfg']['NumFavoriteTables'] > 0) {
$retval .= PMA_FavoriteTable::getInstance()->getHtmlSelect();
$retval .= PMA_RecentFavoriteTable::getInstance('favorite')->getHtmlSelect();
}
return $retval;
}

View File

@ -478,22 +478,9 @@ function PMA_getHtmlForStructureTableRow(
. '</td>';
}
//Favorite table anchor.
$html_output .= '<td class="center">';
$html_output .= '<a ';
$html_output .= 'class="ajax favorite_table_anchor';
if ($table_is_view || $current_table['ENGINE'] == null) {
// this class is used in db_structure.js to display the
// correct confirmation message
$html_output .= ' view';
}
// Check if current table is already in favorite list.
$already_favorite = PMA_checkFavoriteTable($db, $current_table['TABLE_NAME']);
$html_output .= '" ';
$html_output .= 'href="db_structure.php?&amp;'. PMA_URL_getCommon($db)
. '&amp;' . ($already_favorite?'remove':'add') . '_favorite=1'
.'&amp;favorite_table=' . urlencode($current_table['TABLE_NAME'])
. '" title="' . ($already_favorite ? __("Remove from Favorites") : __("Add to Favorites")) . '" >'
. (!$already_favorite ? $titles['NoFavorite'] : $titles['Favorite']) . '</a></td>';
$html_output .= '<td class="center">'
. PMA_getHtmlForFavoriteAnchor($db, $current_table, $titles)
.'</td>';
$html_output .= '<td class="center">' . $browse_table . '</td>';
$html_output .= '<td class="center">'
@ -2711,4 +2698,36 @@ function PMA_checkFavoriteTable($db, $current_table)
}
return false;
}
/**
* Get HTML for favorite anchor.
*
* @param string $db current database
* @param string $current_table current table
* @param string $titles titles
*
* @return $html_output
*/
function PMA_getHtmlForFavoriteAnchor($db, $current_table, $titles)
{
$html_output = '<a ';
$html_output .= 'id="' . preg_replace('/\s+/', '', $current_table['TABLE_NAME']) . '_favorite_anchor" ';
$html_output .= 'class="ajax favorite_table_anchor';
// Check if current table is already in favorite list.
$already_favorite = PMA_checkFavoriteTable($db, $current_table['TABLE_NAME']);
$fav_params = array('db' => $db,
'ajax_request' => true,
'favorite_table' => $current_table['TABLE_NAME'],
(($already_favorite?'remove':'add') . '_favorite') => true);
$fav_url = 'db_structure.php' . PMA_URL_getCommon($fav_params);
$html_output .= '" ';
$html_output .= 'href="' . $fav_url
. '" title="' . ($already_favorite ? __("Remove from Favorites")
: __("Add to Favorites")) . '" >'
. (!$already_favorite ? $titles['NoFavorite']
: $titles['Favorite']) . '</a>';
return $html_output;
}
?>