NodeDatabase.php 24 KB

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