NodeTable.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Functionality for the navigation tree
  5. *
  6. * @package PhpMyAdmin-Navigation
  7. */
  8. namespace PhpMyAdmin\Navigation\Nodes;
  9. use PhpMyAdmin\Util;
  10. /**
  11. * Represents a columns node in the navigation tree
  12. *
  13. * @package PhpMyAdmin-Navigation
  14. */
  15. class NodeTable extends NodeDatabaseChild
  16. {
  17. /**
  18. * Initialises the class
  19. *
  20. * @param string $name An identifier for the new node
  21. * @param int $type Type of node, may be one of CONTAINER or OBJECT
  22. * @param bool $is_group Whether this object has been created
  23. * while grouping nodes
  24. */
  25. public function __construct($name, $type = Node::OBJECT, $is_group = false)
  26. {
  27. parent::__construct($name, $type, $is_group);
  28. $this->icon = array();
  29. $this->_addIcon(
  30. Util::getScriptNameForOption(
  31. $GLOBALS['cfg']['NavigationTreeDefaultTabTable'],
  32. 'table'
  33. )
  34. );
  35. $this->_addIcon(
  36. Util::getScriptNameForOption(
  37. $GLOBALS['cfg']['NavigationTreeDefaultTabTable2'],
  38. 'table'
  39. )
  40. );
  41. $title = Util::getTitleForTarget(
  42. $GLOBALS['cfg']['DefaultTabTable']
  43. );
  44. $this->title = $title;
  45. $script_name = Util::getScriptNameForOption(
  46. $GLOBALS['cfg']['DefaultTabTable'],
  47. 'table'
  48. );
  49. $this->links = array(
  50. 'text' => $script_name
  51. . '?server=' . $GLOBALS['server']
  52. . '&amp;db=%2$s&amp;table=%1$s'
  53. . '&amp;pos=0',
  54. 'icon' => array(
  55. Util::getScriptNameForOption(
  56. $GLOBALS['cfg']['NavigationTreeDefaultTabTable'],
  57. 'table'
  58. )
  59. . '?server=' . $GLOBALS['server']
  60. . '&amp;db=%2$s&amp;table=%1$s',
  61. Util::getScriptNameForOption(
  62. $GLOBALS['cfg']['NavigationTreeDefaultTabTable2'],
  63. 'table'
  64. )
  65. . '?server=' . $GLOBALS['server']
  66. . '&amp;db=%2$s&amp;table=%1$s',
  67. ),
  68. 'title' => $this->title,
  69. );
  70. $this->classes = 'table';
  71. }
  72. /**
  73. * Returns the number of children of type $type present inside this container
  74. * This method is overridden by the PhpMyAdmin\Navigation\Nodes\NodeDatabase
  75. * and PhpMyAdmin\Navigation\Nodes\NodeTable classes
  76. *
  77. * @param string $type The type of item we are looking for
  78. * ('columns' or 'indexes')
  79. * @param string $searchClause A string used to filter the results of the query
  80. *
  81. * @return int
  82. */
  83. public function getPresence($type = '', $searchClause = '')
  84. {
  85. $retval = 0;
  86. $db = $this->realParent()->real_name;
  87. $table = $this->real_name;
  88. switch ($type) {
  89. case 'columns':
  90. if (!$GLOBALS['cfg']['Server']['DisableIS']) {
  91. $db = $GLOBALS['dbi']->escapeString($db);
  92. $table = $GLOBALS['dbi']->escapeString($table);
  93. $query = "SELECT COUNT(*) ";
  94. $query .= "FROM `INFORMATION_SCHEMA`.`COLUMNS` ";
  95. $query .= "WHERE `TABLE_NAME`='$table' ";
  96. $query .= "AND `TABLE_SCHEMA`='$db'";
  97. $retval = (int)$GLOBALS['dbi']->fetchValue($query);
  98. } else {
  99. $db = Util::backquote($db);
  100. $table = Util::backquote($table);
  101. $query = "SHOW COLUMNS FROM $table FROM $db";
  102. $retval = (int)$GLOBALS['dbi']->numRows(
  103. $GLOBALS['dbi']->tryQuery($query)
  104. );
  105. }
  106. break;
  107. case 'indexes':
  108. $db = Util::backquote($db);
  109. $table = Util::backquote($table);
  110. $query = "SHOW INDEXES FROM $table FROM $db";
  111. $retval = (int)$GLOBALS['dbi']->numRows(
  112. $GLOBALS['dbi']->tryQuery($query)
  113. );
  114. break;
  115. case 'triggers':
  116. if (!$GLOBALS['cfg']['Server']['DisableIS']) {
  117. $db = $GLOBALS['dbi']->escapeString($db);
  118. $table = $GLOBALS['dbi']->escapeString($table);
  119. $query = "SELECT COUNT(*) ";
  120. $query .= "FROM `INFORMATION_SCHEMA`.`TRIGGERS` ";
  121. $query .= "WHERE `EVENT_OBJECT_SCHEMA` "
  122. . Util::getCollateForIS() . "='$db' ";
  123. $query .= "AND `EVENT_OBJECT_TABLE` "
  124. . Util::getCollateForIS() . "='$table'";
  125. $retval = (int)$GLOBALS['dbi']->fetchValue($query);
  126. } else {
  127. $db = Util::backquote($db);
  128. $table = $GLOBALS['dbi']->escapeString($table);
  129. $query = "SHOW TRIGGERS FROM $db WHERE `Table` = '$table'";
  130. $retval = (int)$GLOBALS['dbi']->numRows(
  131. $GLOBALS['dbi']->tryQuery($query)
  132. );
  133. }
  134. break;
  135. default:
  136. break;
  137. }
  138. return $retval;
  139. }
  140. /**
  141. * Returns the names of children of type $type present inside this container
  142. * This method is overridden by the PhpMyAdmin\Navigation\Nodes\NodeDatabase
  143. * and PhpMyAdmin\Navigation\Nodes\NodeTable classes
  144. *
  145. * @param string $type The type of item we are looking for
  146. * ('tables', 'views', etc)
  147. * @param int $pos The offset of the list within the results
  148. * @param string $searchClause A string used to filter the results of the query
  149. *
  150. * @return array
  151. */
  152. public function getData($type, $pos, $searchClause = '')
  153. {
  154. $maxItems = $GLOBALS['cfg']['MaxNavigationItems'];
  155. $retval = array();
  156. $db = $this->realParent()->real_name;
  157. $table = $this->real_name;
  158. switch ($type) {
  159. case 'columns':
  160. if (!$GLOBALS['cfg']['Server']['DisableIS']) {
  161. $db = $GLOBALS['dbi']->escapeString($db);
  162. $table = $GLOBALS['dbi']->escapeString($table);
  163. $query = "SELECT `COLUMN_NAME` AS `name` ";
  164. $query .= "FROM `INFORMATION_SCHEMA`.`COLUMNS` ";
  165. $query .= "WHERE `TABLE_NAME`='$table' ";
  166. $query .= "AND `TABLE_SCHEMA`='$db' ";
  167. $query .= "ORDER BY `COLUMN_NAME` ASC ";
  168. $query .= "LIMIT " . intval($pos) . ", $maxItems";
  169. $retval = $GLOBALS['dbi']->fetchResult($query);
  170. break;
  171. }
  172. $db = Util::backquote($db);
  173. $table = Util::backquote($table);
  174. $query = "SHOW COLUMNS FROM $table FROM $db";
  175. $handle = $GLOBALS['dbi']->tryQuery($query);
  176. if ($handle === false) {
  177. break;
  178. }
  179. $count = 0;
  180. if ($GLOBALS['dbi']->dataSeek($handle, $pos)) {
  181. while ($arr = $GLOBALS['dbi']->fetchArray($handle)) {
  182. if ($count < $maxItems) {
  183. $retval[] = $arr['Field'];
  184. $count++;
  185. } else {
  186. break;
  187. }
  188. }
  189. }
  190. break;
  191. case 'indexes':
  192. $db = Util::backquote($db);
  193. $table = Util::backquote($table);
  194. $query = "SHOW INDEXES FROM $table FROM $db";
  195. $handle = $GLOBALS['dbi']->tryQuery($query);
  196. if ($handle === false) {
  197. break;
  198. }
  199. $count = 0;
  200. while ($arr = $GLOBALS['dbi']->fetchArray($handle)) {
  201. if (in_array($arr['Key_name'], $retval)) {
  202. continue;
  203. }
  204. if ($pos <= 0 && $count < $maxItems) {
  205. $retval[] = $arr['Key_name'];
  206. $count++;
  207. }
  208. $pos--;
  209. }
  210. break;
  211. case 'triggers':
  212. if (!$GLOBALS['cfg']['Server']['DisableIS']) {
  213. $db = $GLOBALS['dbi']->escapeString($db);
  214. $table = $GLOBALS['dbi']->escapeString($table);
  215. $query = "SELECT `TRIGGER_NAME` AS `name` ";
  216. $query .= "FROM `INFORMATION_SCHEMA`.`TRIGGERS` ";
  217. $query .= "WHERE `EVENT_OBJECT_SCHEMA` "
  218. . Util::getCollateForIS() . "='$db' ";
  219. $query .= "AND `EVENT_OBJECT_TABLE` "
  220. . Util::getCollateForIS() . "='$table' ";
  221. $query .= "ORDER BY `TRIGGER_NAME` ASC ";
  222. $query .= "LIMIT " . intval($pos) . ", $maxItems";
  223. $retval = $GLOBALS['dbi']->fetchResult($query);
  224. break;
  225. }
  226. $db = Util::backquote($db);
  227. $table = $GLOBALS['dbi']->escapeString($table);
  228. $query = "SHOW TRIGGERS FROM $db WHERE `Table` = '$table'";
  229. $handle = $GLOBALS['dbi']->tryQuery($query);
  230. if ($handle === false) {
  231. break;
  232. }
  233. $count = 0;
  234. if ($GLOBALS['dbi']->dataSeek($handle, $pos)) {
  235. while ($arr = $GLOBALS['dbi']->fetchArray($handle)) {
  236. if ($count < $maxItems) {
  237. $retval[] = $arr['Trigger'];
  238. $count++;
  239. } else {
  240. break;
  241. }
  242. }
  243. }
  244. break;
  245. default:
  246. break;
  247. }
  248. return $retval;
  249. }
  250. /**
  251. * Returns the type of the item represented by the node.
  252. *
  253. * @return string type of the item
  254. */
  255. protected function getItemType()
  256. {
  257. return 'table';
  258. }
  259. /**
  260. * Add an icon to navigation tree
  261. *
  262. * @param string $page Page name to redirect
  263. *
  264. * @return void
  265. */
  266. private function _addIcon($page)
  267. {
  268. if (empty($page)) {
  269. return;
  270. }
  271. switch ($page) {
  272. case 'tbl_structure.php':
  273. $this->icon[] = Util::getImage('b_props', __('Structure'));
  274. break;
  275. case 'tbl_select.php':
  276. $this->icon[] = Util::getImage('b_search', __('Search'));
  277. break;
  278. case 'tbl_change.php':
  279. $this->icon[] = Util::getImage('b_insrow', __('Insert'));
  280. break;
  281. case 'tbl_sql.php':
  282. $this->icon[] = Util::getImage('b_sql', __('SQL'));
  283. break;
  284. case 'sql.php':
  285. $this->icon[] = Util::getImage('b_browse', __('Browse'));
  286. break;
  287. }
  288. }
  289. }