RecentFavoriteTable.class.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Recent and Favorite table list handling
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. if (! defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. require_once './libraries/Message.class.php';
  12. /**
  13. * Handles the recently used and favorite tables.
  14. *
  15. * @TODO Change the release version in table pma_recent
  16. * (#recent in documentation)
  17. *
  18. * @package PhpMyAdmin
  19. */
  20. class PMA_RecentFavoriteTable
  21. {
  22. /**
  23. * Defines the internal PMA table which contains recent/favorite tables.
  24. *
  25. * @access private
  26. * @var string
  27. */
  28. private $_pmaTable;
  29. /**
  30. * Reference to session variable containing recently used or favorite tables.
  31. *
  32. * @access private
  33. * @var array
  34. */
  35. private $_tables;
  36. /**
  37. * Defines type of action, Favorite or Recent table.
  38. *
  39. * @access private
  40. * @var string
  41. */
  42. private $_tableType;
  43. /**
  44. * PMA_RecentFavoriteTable instances.
  45. *
  46. * @access private
  47. * @var array
  48. */
  49. private static $_instances = array();
  50. /**
  51. * Creates a new instance of PMA_RecentFavoriteTable
  52. *
  53. * @access private
  54. * @param string $type the table type
  55. */
  56. private function __construct($type)
  57. {
  58. $this->_tableType = $type;
  59. if (strlen($GLOBALS['cfg']['Server']['pmadb'])
  60. && strlen($GLOBALS['cfg']['Server'][$this->_tableType])
  61. ) {
  62. $this->_pmaTable
  63. = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "."
  64. . PMA_Util::backquote($GLOBALS['cfg']['Server'][$this->_tableType]);
  65. }
  66. $server_id = $GLOBALS['server'];
  67. if (! isset($_SESSION['tmpval'][$this->_tableType . '_tables'][$server_id])) {
  68. $_SESSION['tmpval'][$this->_tableType . '_tables'][$server_id]
  69. = isset($this->_pmaTable) ? $this->getFromDb() : array();
  70. }
  71. $this->_tables =& $_SESSION['tmpval'][$this->_tableType . '_tables'][$server_id];
  72. }
  73. /**
  74. * Returns class instance.
  75. *
  76. * @param string $type the table type
  77. *
  78. * @return PMA_RecentFavoriteTable
  79. */
  80. public static function getInstance($type)
  81. {
  82. if (! array_key_exists($type, self::$_instances)) {
  83. self::$_instances[$type] = new PMA_RecentFavoriteTable($type);
  84. }
  85. return self::$_instances[$type];
  86. }
  87. /**
  88. * Returns the recent/favorite tables array
  89. *
  90. * @return array
  91. */
  92. public function getTables()
  93. {
  94. return $this->_tables;
  95. }
  96. /**
  97. * Returns recently used tables or favorite from phpMyAdmin database.
  98. *
  99. * @return array
  100. */
  101. public function getFromDb()
  102. {
  103. // Read from phpMyAdmin database, if recent tables is not in session
  104. $sql_query
  105. = " SELECT `tables` FROM " . $this->_pmaTable .
  106. " WHERE `username` = '" . $GLOBALS['cfg']['Server']['user'] . "'";
  107. $return = array();
  108. $result = PMA_queryAsControlUser($sql_query, false);
  109. if ($result) {
  110. $row = $GLOBALS['dbi']->fetchArray($result);
  111. if (isset($row[0])) {
  112. $return = json_decode($row[0], true);
  113. }
  114. }
  115. return $return;
  116. }
  117. /**
  118. * Save recent/favorite tables into phpMyAdmin database.
  119. *
  120. * @return true|PMA_Message
  121. */
  122. public function saveToDb()
  123. {
  124. $username = $GLOBALS['cfg']['Server']['user'];
  125. $sql_query
  126. = " REPLACE INTO " . $this->_pmaTable . " (`username`, `tables`)" .
  127. " VALUES ('" . $username . "', '"
  128. . PMA_Util::sqlAddSlashes(
  129. json_encode($this->_tables)
  130. ) . "')";
  131. $success = $GLOBALS['dbi']->tryQuery($sql_query, $GLOBALS['controllink']);
  132. if (! $success) {
  133. $error_msg = '';
  134. switch ($this->_tableType) {
  135. case 'recent':
  136. $error_msg = __('Could not save recent table!');
  137. break;
  138. case 'favorite':
  139. $error_msg = __('Could not save favorite table!');
  140. break;
  141. }
  142. $message = PMA_Message::error($error_msg);
  143. $message->addMessage('<br /><br />');
  144. $message->addMessage(
  145. PMA_Message::rawError(
  146. $GLOBALS['dbi']->getError($GLOBALS['controllink'])
  147. )
  148. );
  149. return $message;
  150. }
  151. return true;
  152. }
  153. /**
  154. * Trim recent.favorite table according to the
  155. * NumRecentTables/NumFavoriteTables configuration.
  156. *
  157. * @return boolean True if trimming occurred
  158. */
  159. public function trim()
  160. {
  161. $max = max(
  162. $GLOBALS['cfg']['Num' . ucfirst($this->_tableType) . 'Tables'], 0
  163. );
  164. $trimming_occurred = count($this->_tables) > $max;
  165. while (count($this->_tables) > $max) {
  166. array_pop($this->_tables);
  167. }
  168. return $trimming_occurred;
  169. }
  170. /**
  171. * Return HTML ul.
  172. *
  173. * @return string
  174. */
  175. public function getHtmlList()
  176. {
  177. // Remove Recent/Favorite tables that don't exist.
  178. foreach ($this->_tables as $tbl) {
  179. if (! $GLOBALS['dbi']->getColumns($tbl['db'], $tbl['table'])) {
  180. $this->remove($tbl['db'], $tbl['table']);
  181. }
  182. }
  183. $html = '';
  184. if (count($this->_tables)) {
  185. if ($this->_tableType == 'recent') {
  186. foreach ($this->_tables as $table) {
  187. $html .= '<li class="warp_link">';
  188. $recent_params = array(
  189. 'db' => $table['db'],
  190. 'table' => $table['table']
  191. );
  192. $recent_url = 'sql.php'
  193. . PMA_URL_getCommon($recent_params);
  194. $html .= '<a href="' . $recent_url . '">`'
  195. . htmlspecialchars($table['db']) . '`.`'
  196. . htmlspecialchars($table['table']) . '`</a>';
  197. $html .= '</li>';
  198. }
  199. } else {
  200. foreach ($this->_tables as $table) {
  201. $html .= '<li class="warp_link">';
  202. $html .= '<a class="ajax favorite_table_anchor" ';
  203. $fav_params = array(
  204. 'db' => $table['db'],
  205. 'ajax_request' => true,
  206. 'favorite_table' => $table['table'],
  207. 'remove_favorite' => true
  208. );
  209. $fav_rm_url = 'db_structure.php'
  210. . PMA_URL_getCommon($fav_params);
  211. $html .= 'href="' . $fav_rm_url
  212. . '" title="' . __("Remove from Favorites")
  213. . '" data-favtargetn="'
  214. . md5($table['db'] . "." . $table['table'])
  215. . '" >'
  216. . PMA_Util::getIcon('b_favorite.png')
  217. . '</a>';
  218. $fav_params = array(
  219. 'db' => $table['db'],
  220. 'table' => $table['table']
  221. );
  222. $table_url = 'sql.php'
  223. . PMA_URL_getCommon($fav_params);
  224. $html .= '<a href="' . $table_url . '">`'
  225. . htmlspecialchars($table['db']) . '`.`'
  226. . htmlspecialchars($table['table']) . '`</a>';
  227. $html .= '</li>';
  228. }
  229. }
  230. } else {
  231. $html .= '<li class="warp_link">'
  232. . ($this->_tableType == 'recent'
  233. ?__('There are no recent tables.')
  234. :__('There are no favorite tables.'))
  235. . '</li>';
  236. }
  237. return $html;
  238. }
  239. /**
  240. * Return HTML.
  241. *
  242. * @return string
  243. */
  244. public function getHtml()
  245. {
  246. $html = '<div class="drop_list">';
  247. if ($this->_tableType == 'recent') {
  248. $html .= '<span title="' . __('Recent tables')
  249. . '" class="drop_button">'
  250. . __('Recent') . '</span><ul id="pma_recent_list">';
  251. } else {
  252. $html .= '<span title="' . __('Favorite tables')
  253. . '" class="drop_button">'
  254. . __('Favorites') . '</span><ul id="pma_favorite_list">';
  255. }
  256. $html .= $this->getHtmlList();
  257. $html .= '</ul></div>';
  258. return $html;
  259. }
  260. /**
  261. * Add recently used or favorite tables.
  262. *
  263. * @param string $db database name where the table is located
  264. * @param string $table table name
  265. *
  266. * @return true|PMA_Message True if success, PMA_Message if not
  267. */
  268. public function add($db, $table)
  269. {
  270. // If table doesnot exist, do not add.
  271. if (! $GLOBALS['dbi']->getColumns($db, $table)) {
  272. return true;
  273. }
  274. $table_arr = array();
  275. $table_arr['db'] = $db;
  276. $table_arr['table'] = $table;
  277. // add only if this is new table
  278. if (! isset($this->_tables[0]) || $this->_tables[0] != $table_arr) {
  279. array_unshift($this->_tables, $table_arr);
  280. $this->_tables = array_merge(array_unique($this->_tables, SORT_REGULAR));
  281. $this->trim();
  282. if (isset($this->_pmaTable)) {
  283. return $this->saveToDb();
  284. }
  285. }
  286. return true;
  287. }
  288. /**
  289. * Remove favorite tables.
  290. *
  291. * @param string $db database name where the table is located
  292. * @param string $table table name
  293. *
  294. * @return true|PMA_Message True if success, PMA_Message if not
  295. */
  296. public function remove($db, $table)
  297. {
  298. $table_arr = array();
  299. $table_arr['db'] = $db;
  300. $table_arr['table'] = $table;
  301. foreach ($this->_tables as $key => $value) {
  302. if ($value['db'] == $db && $value['table'] == $table) {
  303. unset($this->_tables[$key]);
  304. }
  305. }
  306. if (isset($this->_pmaTable)) {
  307. return $this->saveToDb();
  308. }
  309. return true;
  310. }
  311. /**
  312. * Generate Html for sync Favorite tables anchor. (from localStorage to pmadb)
  313. *
  314. * @return string
  315. */
  316. public function getHtmlSyncFavoriteTables()
  317. {
  318. $retval = '';
  319. $server_id = $GLOBALS['server'];
  320. // Not to show this once list is synchronized.
  321. $is_synced = isset($_SESSION['tmpval']['favorites_synced'][$server_id]) ?
  322. true : false;
  323. if (!$is_synced) {
  324. $params = array('ajax_request' => true, 'favorite_table' => true,
  325. 'sync_favorite_tables' => true);
  326. $url = 'db_structure.php' . PMA_URL_getCommon($params);
  327. $retval = '<a class="hide" id="sync_favorite_tables"';
  328. $retval .= ' href="' . $url . '"></a>';
  329. }
  330. return $retval;
  331. }
  332. }
  333. ?>