NodeDatabase.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  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. declare(strict_types=1);
  9. namespace PhpMyAdmin\Navigation\Nodes;
  10. use PhpMyAdmin\Relation;
  11. use PhpMyAdmin\Url;
  12. use PhpMyAdmin\Util;
  13. /**
  14. * Represents a database node in the navigation tree
  15. *
  16. * @package PhpMyAdmin-Navigation
  17. */
  18. class NodeDatabase extends Node
  19. {
  20. /**
  21. * The number of hidden items in this database
  22. *
  23. * @var int
  24. */
  25. protected $hiddenCount = 0;
  26. /**
  27. * Initialises the class
  28. *
  29. * @param string $name An identifier for the new node
  30. * @param int $type Type of node, may be one of CONTAINER or OBJECT
  31. * @param bool $isGroup Whether this object has been created
  32. * while grouping nodes
  33. */
  34. public function __construct($name, $type = Node::OBJECT, $isGroup = false)
  35. {
  36. parent::__construct($name, $type, $isGroup);
  37. $this->icon = Util::getImage(
  38. 's_db',
  39. __('Database operations')
  40. );
  41. $scriptName = Util::getScriptNameForOption(
  42. $GLOBALS['cfg']['DefaultTabDatabase'],
  43. 'database'
  44. );
  45. $this->links = [
  46. 'text' => $scriptName
  47. . '?server=' . $GLOBALS['server']
  48. . '&amp;db=%1$s',
  49. 'icon' => 'db_operations.php?server=' . $GLOBALS['server']
  50. . '&amp;db=%1$s&amp;',
  51. 'title' => __('Structure'),
  52. ];
  53. $this->classes = 'database';
  54. }
  55. /**
  56. * Returns the number of children of type $type present inside this container
  57. * This method is overridden by the PhpMyAdmin\Navigation\Nodes\NodeDatabase
  58. * and PhpMyAdmin\Navigation\Nodes\NodeTable classes
  59. *
  60. * @param string $type The type of item we are looking for
  61. * ('tables', 'views', etc)
  62. * @param string $searchClause A string used to filter the results of
  63. * the query
  64. * @param boolean $singleItem Whether to get presence of a single known
  65. * item or false in none
  66. *
  67. * @return int
  68. */
  69. public function getPresence($type = '', $searchClause = '', $singleItem = false)
  70. {
  71. $retval = 0;
  72. switch ($type) {
  73. case 'tables':
  74. $retval = $this->getTableCount($searchClause, $singleItem);
  75. break;
  76. case 'views':
  77. $retval = $this->getViewCount($searchClause, $singleItem);
  78. break;
  79. case 'procedures':
  80. $retval = $this->getProcedureCount($searchClause, $singleItem);
  81. break;
  82. case 'functions':
  83. $retval = $this->getFunctionCount($searchClause, $singleItem);
  84. break;
  85. case 'events':
  86. $retval = $this->getEventCount($searchClause, $singleItem);
  87. break;
  88. default:
  89. break;
  90. }
  91. return $retval;
  92. }
  93. /**
  94. * Returns the number of tables or views present inside this database
  95. *
  96. * @param string $which tables|views
  97. * @param string $searchClause A string used to filter the results of
  98. * the query
  99. * @param boolean $singleItem Whether to get presence of a single known
  100. * item or false in none
  101. *
  102. * @return int
  103. */
  104. private function getTableOrViewCount($which, $searchClause, $singleItem)
  105. {
  106. $db = $this->realName;
  107. if ($which == 'tables') {
  108. $condition = 'IN';
  109. } else {
  110. $condition = 'NOT IN';
  111. }
  112. if (! $GLOBALS['cfg']['Server']['DisableIS']) {
  113. $db = $GLOBALS['dbi']->escapeString($db);
  114. $query = "SELECT COUNT(*) ";
  115. $query .= "FROM `INFORMATION_SCHEMA`.`TABLES` ";
  116. $query .= "WHERE `TABLE_SCHEMA`='$db' ";
  117. $query .= "AND `TABLE_TYPE`" . $condition . "('BASE TABLE', 'SYSTEM VERSIONED') ";
  118. if (! empty($searchClause)) {
  119. $query .= "AND " . $this->getWhereClauseForSearch(
  120. $searchClause,
  121. $singleItem,
  122. 'TABLE_NAME'
  123. );
  124. }
  125. $retval = (int) $GLOBALS['dbi']->fetchValue($query);
  126. } else {
  127. $query = "SHOW FULL TABLES FROM ";
  128. $query .= Util::backquote($db);
  129. $query .= " WHERE `Table_type`" . $condition . "('BASE TABLE', 'SYSTEM VERSIONED') ";
  130. if (! empty($searchClause)) {
  131. $query .= "AND " . $this->getWhereClauseForSearch(
  132. $searchClause,
  133. $singleItem,
  134. 'Tables_in_' . $db
  135. );
  136. }
  137. $retval = $GLOBALS['dbi']->numRows(
  138. $GLOBALS['dbi']->tryQuery($query)
  139. );
  140. }
  141. return $retval;
  142. }
  143. /**
  144. * Returns the number of tables present inside this database
  145. *
  146. * @param string $searchClause A string used to filter the results of
  147. * the query
  148. * @param boolean $singleItem Whether to get presence of a single known
  149. * item or false in none
  150. *
  151. * @return int
  152. */
  153. private function getTableCount($searchClause, $singleItem)
  154. {
  155. return $this->getTableOrViewCount(
  156. 'tables',
  157. $searchClause,
  158. $singleItem
  159. );
  160. }
  161. /**
  162. * Returns the number of views present inside this database
  163. *
  164. * @param string $searchClause A string used to filter the results of
  165. * the query
  166. * @param boolean $singleItem Whether to get presence of a single known
  167. * item or false in none
  168. *
  169. * @return int
  170. */
  171. private function getViewCount($searchClause, $singleItem)
  172. {
  173. return $this->getTableOrViewCount(
  174. 'views',
  175. $searchClause,
  176. $singleItem
  177. );
  178. }
  179. /**
  180. * Returns the number of procedures present inside this database
  181. *
  182. * @param string $searchClause A string used to filter the results of
  183. * the query
  184. * @param boolean $singleItem Whether to get presence of a single known
  185. * item or false in none
  186. *
  187. * @return int
  188. */
  189. private function getProcedureCount($searchClause, $singleItem)
  190. {
  191. $db = $this->realName;
  192. if (! $GLOBALS['cfg']['Server']['DisableIS']) {
  193. $db = $GLOBALS['dbi']->escapeString($db);
  194. $query = "SELECT COUNT(*) ";
  195. $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` ";
  196. $query .= "WHERE `ROUTINE_SCHEMA` "
  197. . Util::getCollateForIS() . "='$db'";
  198. $query .= "AND `ROUTINE_TYPE`='PROCEDURE' ";
  199. if (! empty($searchClause)) {
  200. $query .= "AND " . $this->getWhereClauseForSearch(
  201. $searchClause,
  202. $singleItem,
  203. 'ROUTINE_NAME'
  204. );
  205. }
  206. $retval = (int) $GLOBALS['dbi']->fetchValue($query);
  207. } else {
  208. $db = $GLOBALS['dbi']->escapeString($db);
  209. $query = "SHOW PROCEDURE STATUS WHERE `Db`='$db' ";
  210. if (! empty($searchClause)) {
  211. $query .= "AND " . $this->getWhereClauseForSearch(
  212. $searchClause,
  213. $singleItem,
  214. 'Name'
  215. );
  216. }
  217. $retval = $GLOBALS['dbi']->numRows(
  218. $GLOBALS['dbi']->tryQuery($query)
  219. );
  220. }
  221. return $retval;
  222. }
  223. /**
  224. * Returns the number of functions present inside this database
  225. *
  226. * @param string $searchClause A string used to filter the results of
  227. * the query
  228. * @param boolean $singleItem Whether to get presence of a single known
  229. * item or false in none
  230. *
  231. * @return int
  232. */
  233. private function getFunctionCount($searchClause, $singleItem)
  234. {
  235. $db = $this->realName;
  236. if (! $GLOBALS['cfg']['Server']['DisableIS']) {
  237. $db = $GLOBALS['dbi']->escapeString($db);
  238. $query = "SELECT COUNT(*) ";
  239. $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` ";
  240. $query .= "WHERE `ROUTINE_SCHEMA` "
  241. . Util::getCollateForIS() . "='$db' ";
  242. $query .= "AND `ROUTINE_TYPE`='FUNCTION' ";
  243. if (! empty($searchClause)) {
  244. $query .= "AND " . $this->getWhereClauseForSearch(
  245. $searchClause,
  246. $singleItem,
  247. 'ROUTINE_NAME'
  248. );
  249. }
  250. $retval = (int) $GLOBALS['dbi']->fetchValue($query);
  251. } else {
  252. $db = $GLOBALS['dbi']->escapeString($db);
  253. $query = "SHOW FUNCTION STATUS WHERE `Db`='$db' ";
  254. if (! empty($searchClause)) {
  255. $query .= "AND " . $this->getWhereClauseForSearch(
  256. $searchClause,
  257. $singleItem,
  258. 'Name'
  259. );
  260. }
  261. $retval = $GLOBALS['dbi']->numRows(
  262. $GLOBALS['dbi']->tryQuery($query)
  263. );
  264. }
  265. return $retval;
  266. }
  267. /**
  268. * Returns the number of events present inside this database
  269. *
  270. * @param string $searchClause A string used to filter the results of
  271. * the query
  272. * @param boolean $singleItem Whether to get presence of a single known
  273. * item or false in none
  274. *
  275. * @return int
  276. */
  277. private function getEventCount($searchClause, $singleItem)
  278. {
  279. $db = $this->realName;
  280. if (! $GLOBALS['cfg']['Server']['DisableIS']) {
  281. $db = $GLOBALS['dbi']->escapeString($db);
  282. $query = "SELECT COUNT(*) ";
  283. $query .= "FROM `INFORMATION_SCHEMA`.`EVENTS` ";
  284. $query .= "WHERE `EVENT_SCHEMA` "
  285. . Util::getCollateForIS() . "='$db' ";
  286. if (! empty($searchClause)) {
  287. $query .= "AND " . $this->getWhereClauseForSearch(
  288. $searchClause,
  289. $singleItem,
  290. 'EVENT_NAME'
  291. );
  292. }
  293. $retval = (int) $GLOBALS['dbi']->fetchValue($query);
  294. } else {
  295. $db = Util::backquote($db);
  296. $query = "SHOW EVENTS FROM $db ";
  297. if (! empty($searchClause)) {
  298. $query .= "WHERE " . $this->getWhereClauseForSearch(
  299. $searchClause,
  300. $singleItem,
  301. 'Name'
  302. );
  303. }
  304. $retval = $GLOBALS['dbi']->numRows(
  305. $GLOBALS['dbi']->tryQuery($query)
  306. );
  307. }
  308. return $retval;
  309. }
  310. /**
  311. * Returns the WHERE clause for searching inside a database
  312. *
  313. * @param string $searchClause A string used to filter the results of the query
  314. * @param boolean $singleItem Whether to get presence of a single known item
  315. * @param string $columnName Name of the column in the result set to match
  316. *
  317. * @return string WHERE clause for searching
  318. */
  319. private function getWhereClauseForSearch(
  320. $searchClause,
  321. $singleItem,
  322. $columnName
  323. ) {
  324. $query = '';
  325. if ($singleItem) {
  326. $query .= Util::backquote($columnName) . " = ";
  327. $query .= "'" . $GLOBALS['dbi']->escapeString($searchClause) . "'";
  328. } else {
  329. $query .= Util::backquote($columnName) . " LIKE ";
  330. $query .= "'%" . $GLOBALS['dbi']->escapeString($searchClause)
  331. . "%'";
  332. }
  333. return $query;
  334. }
  335. /**
  336. * Returns the names of children of type $type present inside this container
  337. * This method is overridden by the PhpMyAdmin\Navigation\Nodes\NodeDatabase
  338. * and PhpMyAdmin\Navigation\Nodes\NodeTable classes
  339. *
  340. * @param string $type The type of item we are looking for
  341. * ('tables', 'views', etc)
  342. * @param int $pos The offset of the list within the results
  343. * @param string $searchClause A string used to filter the results of the query
  344. *
  345. * @return array
  346. */
  347. public function getData($type, $pos, $searchClause = '')
  348. {
  349. $retval = [];
  350. switch ($type) {
  351. case 'tables':
  352. $retval = $this->getTables($pos, $searchClause);
  353. break;
  354. case 'views':
  355. $retval = $this->getViews($pos, $searchClause);
  356. break;
  357. case 'procedures':
  358. $retval = $this->getProcedures($pos, $searchClause);
  359. break;
  360. case 'functions':
  361. $retval = $this->getFunctions($pos, $searchClause);
  362. break;
  363. case 'events':
  364. $retval = $this->getEvents($pos, $searchClause);
  365. break;
  366. default:
  367. break;
  368. }
  369. // Remove hidden items so that they are not displayed in navigation tree
  370. $cfgRelation = $this->relation->getRelationsParam();
  371. if ($cfgRelation['navwork']) {
  372. $hiddenItems = $this->getHiddenItems(substr($type, 0, -1));
  373. foreach ($retval as $key => $item) {
  374. if (in_array($item, $hiddenItems)) {
  375. unset($retval[$key]);
  376. }
  377. }
  378. }
  379. return $retval;
  380. }
  381. /**
  382. * Return list of hidden items of given type
  383. *
  384. * @param string $type The type of items we are looking for
  385. * ('table', 'function', 'group', etc.)
  386. *
  387. * @return array Array containing hidden items of given type
  388. */
  389. public function getHiddenItems($type)
  390. {
  391. $db = $this->realName;
  392. $cfgRelation = $this->relation->getRelationsParam();
  393. if (! $cfgRelation['navwork']) {
  394. return [];
  395. }
  396. $navTable = Util::backquote($cfgRelation['db'])
  397. . "." . Util::backquote($cfgRelation['navigationhiding']);
  398. $sqlQuery = "SELECT `item_name` FROM " . $navTable
  399. . " WHERE `username`='" . $cfgRelation['user'] . "'"
  400. . " AND `item_type`='" . $type
  401. . "' AND `db_name`='" . $GLOBALS['dbi']->escapeString($db)
  402. . "'";
  403. $result = $this->relation->queryAsControlUser($sqlQuery, false);
  404. $hiddenItems = [];
  405. if ($result) {
  406. while ($row = $GLOBALS['dbi']->fetchArray($result)) {
  407. $hiddenItems[] = $row[0];
  408. }
  409. }
  410. $GLOBALS['dbi']->freeResult($result);
  411. return $hiddenItems;
  412. }
  413. /**
  414. * Returns the list of tables or views inside this database
  415. *
  416. * @param string $which tables|views
  417. * @param int $pos The offset of the list within the results
  418. * @param string $searchClause A string used to filter the results of the query
  419. *
  420. * @return array
  421. */
  422. private function getTablesOrViews($which, $pos, $searchClause)
  423. {
  424. if ($which == 'tables') {
  425. $condition = 'IN';
  426. } else {
  427. $condition = 'NOT IN';
  428. }
  429. $maxItems = $GLOBALS['cfg']['MaxNavigationItems'];
  430. $retval = [];
  431. $db = $this->realName;
  432. if (! $GLOBALS['cfg']['Server']['DisableIS']) {
  433. $escdDb = $GLOBALS['dbi']->escapeString($db);
  434. $query = "SELECT `TABLE_NAME` AS `name` ";
  435. $query .= "FROM `INFORMATION_SCHEMA`.`TABLES` ";
  436. $query .= "WHERE `TABLE_SCHEMA`='$escdDb' ";
  437. $query .= "AND `TABLE_TYPE`" . $condition . "('BASE TABLE', 'SYSTEM VERSIONED') ";
  438. if (! empty($searchClause)) {
  439. $query .= "AND `TABLE_NAME` LIKE '%";
  440. $query .= $GLOBALS['dbi']->escapeString($searchClause);
  441. $query .= "%'";
  442. }
  443. $query .= "ORDER BY `TABLE_NAME` ASC ";
  444. $query .= "LIMIT " . intval($pos) . ", $maxItems";
  445. $retval = $GLOBALS['dbi']->fetchResult($query);
  446. } else {
  447. $query = " SHOW FULL TABLES FROM ";
  448. $query .= Util::backquote($db);
  449. $query .= " WHERE `Table_type`" . $condition . "('BASE TABLE', 'SYSTEM VERSIONED') ";
  450. if (! empty($searchClause)) {
  451. $query .= "AND " . Util::backquote(
  452. "Tables_in_" . $db
  453. );
  454. $query .= " LIKE '%" . $GLOBALS['dbi']->escapeString(
  455. $searchClause
  456. );
  457. $query .= "%'";
  458. }
  459. $handle = $GLOBALS['dbi']->tryQuery($query);
  460. if ($handle !== false) {
  461. $count = 0;
  462. if ($GLOBALS['dbi']->dataSeek($handle, $pos)) {
  463. while ($arr = $GLOBALS['dbi']->fetchArray($handle)) {
  464. if ($count < $maxItems) {
  465. $retval[] = $arr[0];
  466. $count++;
  467. } else {
  468. break;
  469. }
  470. }
  471. }
  472. }
  473. }
  474. return $retval;
  475. }
  476. /**
  477. * Returns the list of tables inside this database
  478. *
  479. * @param int $pos The offset of the list within the results
  480. * @param string $searchClause A string used to filter the results of the query
  481. *
  482. * @return array
  483. */
  484. private function getTables($pos, $searchClause)
  485. {
  486. return $this->getTablesOrViews('tables', $pos, $searchClause);
  487. }
  488. /**
  489. * Returns the list of views inside this database
  490. *
  491. * @param int $pos The offset of the list within the results
  492. * @param string $searchClause A string used to filter the results of the query
  493. *
  494. * @return array
  495. */
  496. private function getViews($pos, $searchClause)
  497. {
  498. return $this->getTablesOrViews('views', $pos, $searchClause);
  499. }
  500. /**
  501. * Returns the list of procedures or functions inside this database
  502. *
  503. * @param string $routineType PROCEDURE|FUNCTION
  504. * @param int $pos The offset of the list within the results
  505. * @param string $searchClause A string used to filter the results of the query
  506. *
  507. * @return array
  508. */
  509. private function getRoutines($routineType, $pos, $searchClause)
  510. {
  511. $maxItems = $GLOBALS['cfg']['MaxNavigationItems'];
  512. $retval = [];
  513. $db = $this->realName;
  514. if (! $GLOBALS['cfg']['Server']['DisableIS']) {
  515. $escdDb = $GLOBALS['dbi']->escapeString($db);
  516. $query = "SELECT `ROUTINE_NAME` AS `name` ";
  517. $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` ";
  518. $query .= "WHERE `ROUTINE_SCHEMA` "
  519. . Util::getCollateForIS() . "='$escdDb'";
  520. $query .= "AND `ROUTINE_TYPE`='" . $routineType . "' ";
  521. if (! empty($searchClause)) {
  522. $query .= "AND `ROUTINE_NAME` LIKE '%";
  523. $query .= $GLOBALS['dbi']->escapeString($searchClause);
  524. $query .= "%'";
  525. }
  526. $query .= "ORDER BY `ROUTINE_NAME` ASC ";
  527. $query .= "LIMIT " . intval($pos) . ", $maxItems";
  528. $retval = $GLOBALS['dbi']->fetchResult($query);
  529. } else {
  530. $escdDb = $GLOBALS['dbi']->escapeString($db);
  531. $query = "SHOW " . $routineType . " STATUS WHERE `Db`='$escdDb' ";
  532. if (! empty($searchClause)) {
  533. $query .= "AND `Name` LIKE '%";
  534. $query .= $GLOBALS['dbi']->escapeString($searchClause);
  535. $query .= "%'";
  536. }
  537. $handle = $GLOBALS['dbi']->tryQuery($query);
  538. if ($handle !== false) {
  539. $count = 0;
  540. if ($GLOBALS['dbi']->dataSeek($handle, $pos)) {
  541. while ($arr = $GLOBALS['dbi']->fetchArray($handle)) {
  542. if ($count < $maxItems) {
  543. $retval[] = $arr['Name'];
  544. $count++;
  545. } else {
  546. break;
  547. }
  548. }
  549. }
  550. }
  551. }
  552. return $retval;
  553. }
  554. /**
  555. * Returns the list of procedures inside this database
  556. *
  557. * @param int $pos The offset of the list within the results
  558. * @param string $searchClause A string used to filter the results of the query
  559. *
  560. * @return array
  561. */
  562. private function getProcedures($pos, $searchClause)
  563. {
  564. return $this->getRoutines('PROCEDURE', $pos, $searchClause);
  565. }
  566. /**
  567. * Returns the list of functions inside this database
  568. *
  569. * @param int $pos The offset of the list within the results
  570. * @param string $searchClause A string used to filter the results of the query
  571. *
  572. * @return array
  573. */
  574. private function getFunctions($pos, $searchClause)
  575. {
  576. return $this->getRoutines('FUNCTION', $pos, $searchClause);
  577. }
  578. /**
  579. * Returns the list of events inside this database
  580. *
  581. * @param int $pos The offset of the list within the results
  582. * @param string $searchClause A string used to filter the results of the query
  583. *
  584. * @return array
  585. */
  586. private function getEvents($pos, $searchClause)
  587. {
  588. $maxItems = $GLOBALS['cfg']['MaxNavigationItems'];
  589. $retval = [];
  590. $db = $this->realName;
  591. if (! $GLOBALS['cfg']['Server']['DisableIS']) {
  592. $escdDb = $GLOBALS['dbi']->escapeString($db);
  593. $query = "SELECT `EVENT_NAME` AS `name` ";
  594. $query .= "FROM `INFORMATION_SCHEMA`.`EVENTS` ";
  595. $query .= "WHERE `EVENT_SCHEMA` "
  596. . Util::getCollateForIS() . "='$escdDb' ";
  597. if (! empty($searchClause)) {
  598. $query .= "AND `EVENT_NAME` LIKE '%";
  599. $query .= $GLOBALS['dbi']->escapeString($searchClause);
  600. $query .= "%'";
  601. }
  602. $query .= "ORDER BY `EVENT_NAME` ASC ";
  603. $query .= "LIMIT " . intval($pos) . ", $maxItems";
  604. $retval = $GLOBALS['dbi']->fetchResult($query);
  605. } else {
  606. $escdDb = Util::backquote($db);
  607. $query = "SHOW EVENTS FROM $escdDb ";
  608. if (! empty($searchClause)) {
  609. $query .= "WHERE `Name` LIKE '%";
  610. $query .= $GLOBALS['dbi']->escapeString($searchClause);
  611. $query .= "%'";
  612. }
  613. $handle = $GLOBALS['dbi']->tryQuery($query);
  614. if ($handle !== false) {
  615. $count = 0;
  616. if ($GLOBALS['dbi']->dataSeek($handle, $pos)) {
  617. while ($arr = $GLOBALS['dbi']->fetchArray($handle)) {
  618. if ($count < $maxItems) {
  619. $retval[] = $arr['Name'];
  620. $count++;
  621. } else {
  622. break;
  623. }
  624. }
  625. }
  626. }
  627. }
  628. return $retval;
  629. }
  630. /**
  631. * Returns HTML for control buttons displayed infront of a node
  632. *
  633. * @return String HTML for control buttons
  634. */
  635. public function getHtmlForControlButtons()
  636. {
  637. $ret = '';
  638. $cfgRelation = $this->relation->getRelationsParam();
  639. if ($cfgRelation['navwork']) {
  640. if ($this->hiddenCount > 0) {
  641. $params = [
  642. 'showUnhideDialog' => true,
  643. 'dbName' => $this->realName,
  644. ];
  645. $ret = '<span class="dbItemControls">'
  646. . '<a href="navigation.php" data-post="'
  647. . Url::getCommon($params, '') . '"'
  648. . ' class="showUnhide ajax">'
  649. . Util::getImage(
  650. 'show',
  651. __('Show hidden items')
  652. )
  653. . '</a></span>';
  654. }
  655. }
  656. return $ret;
  657. }
  658. /**
  659. * Sets the number of hidden items in this database
  660. *
  661. * @param int $count hidden item count
  662. *
  663. * @return void
  664. */
  665. public function setHiddenCount($count)
  666. {
  667. $this->hiddenCount = $count;
  668. }
  669. /**
  670. * Returns the number of hidden items in this database
  671. *
  672. * @return int hidden item count
  673. */
  674. public function getHiddenCount()
  675. {
  676. return $this->hiddenCount;
  677. }
  678. }