From e9d59fd7e08b1fd5c96d86e0589c75c8d6c4990a Mon Sep 17 00:00:00 2001 From: Ashutosh Dhundhara Date: Fri, 28 Mar 2014 11:48:36 +0530 Subject: [PATCH] Implemented Favorite tables feature with Ajax. Signed-off-by: Ashutosh Dhundhara Minor fixes in Settings->Features page and Navigation Header class. Signed-off-by: Ashutosh Dhundhara Fixed translation issues in RecentFavoriteTable class. Signed-off-by: Ashutosh Dhundhara Fixed error in RecentFavoriteTable class. Signed-off-by: Ashutosh Dhundhara Another fix in structure.lib.php. Signed-off-by: Ashutosh Dhundhara --- db_structure.php | 59 ++++- doc/faq.rst | 22 ++ index.php | 4 +- js/db_structure.js | 27 +++ libraries/Header.class.php | 5 +- ...lass.php => RecentFavoriteTable.class.php} | 124 +++++----- libraries/RecentTable.class.php | 220 ------------------ libraries/config/messages.inc.php | 1 + .../navigation/NavigationHeader.class.php | 14 +- libraries/structure.lib.php | 51 ++-- 10 files changed, 221 insertions(+), 306 deletions(-) rename libraries/{FavoriteTable.class.php => RecentFavoriteTable.class.php} (64%) delete mode 100644 libraries/RecentTable.class.php diff --git a/db_structure.php b/db_structure.php index 63e36fc9c0..ab46c50909 100644 --- a/db_structure.php +++ b/db_structure.php @@ -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 = '
' + . __("Favorite List is full!") + . '
'; + } 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 diff --git a/doc/faq.rst b/doc/faq.rst index 2dde65d14b..0fde66e8ce 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -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 diff --git a/index.php b/index.php index 625b564fcd..2f1cd8efb4 100644 --- a/index.php +++ b/index.php @@ -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; } diff --git a/js/db_structure.js b/js/db_structure.js index 25161811fb..6d667dbe50 100644 --- a/js/db_structure.js +++ b/js/db_structure.js @@ -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 $() diff --git a/libraries/Header.class.php b/libraries/Header.class.php index 14ae45dc24..991293cb40 100644 --- a/libraries/Header.class.php +++ b/libraries/Header.class.php @@ -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); diff --git a/libraries/FavoriteTable.class.php b/libraries/RecentFavoriteTable.class.php similarity index 64% rename from libraries/FavoriteTable.class.php rename to libraries/RecentFavoriteTable.class.php index 4e445e8240..30b28c9b20 100644 --- a/libraries/FavoriteTable.class.php +++ b/libraries/RecentFavoriteTable.class.php @@ -1,7 +1,7 @@ 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('

'); $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('

'); - $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 = ''; + $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 = ''; if (count($this->tables)) { foreach ($this->tables as $table) { $html .= ''; } return $html; @@ -211,7 +219,7 @@ class PMA_FavoriteTable */ public function getHtmlSelect() { - $html = ''; $html .= $this->getHtmlSelectOption(); $html .= ''; @@ -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; } diff --git a/libraries/RecentTable.class.php b/libraries/RecentTable.class.php deleted file mode 100644 index 7cc9621919..0000000000 --- a/libraries/RecentTable.class.php +++ /dev/null @@ -1,220 +0,0 @@ -_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('

'); - $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 = ''; - if (count($this->tables)) { - foreach ($this->tables as $table) { - $html .= ''; - } - } else { - $html .= ''; - } - return $html; - } - - /** - * Return HTML select. - * - * @return string - */ - public function getHtmlSelect() - { - $html = ''; - - 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; - } - -} -?> diff --git a/libraries/config/messages.inc.php b/libraries/config/messages.inc.php index f0032047c3..8b9a209357 100644 --- a/libraries/config/messages.inc.php +++ b/libraries/config/messages.inc.php @@ -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 diff --git a/libraries/navigation/NavigationHeader.class.php b/libraries/navigation/NavigationHeader.class.php index 7577209b60..3764f263af 100644 --- a/libraries/navigation/NavigationHeader.class.php +++ b/libraries/navigation/NavigationHeader.class.php @@ -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 .= ''; $retval .= '
'; $retval .= '
$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 .= '
'; $retval .= '
'; $retval .= ''; @@ -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; } diff --git a/libraries/structure.lib.php b/libraries/structure.lib.php index 69909f56d5..c69789998c 100644 --- a/libraries/structure.lib.php +++ b/libraries/structure.lib.php @@ -478,22 +478,9 @@ function PMA_getHtmlForStructureTableRow( . ''; } //Favorite table anchor. - $html_output .= ''; - $html_output .= '' - . (!$already_favorite ? $titles['NoFavorite'] : $titles['Favorite']) . ''; + $html_output .= '' + . PMA_getHtmlForFavoriteAnchor($db, $current_table, $titles) + .''; $html_output .= '' . $browse_table . ''; $html_output .= '' @@ -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 = ' $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']) . ''; + + return $html_output; +} ?>