Designer.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Holds the PhpMyAdmin\Database\Designer class
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. namespace PhpMyAdmin\Database;
  9. use PhpMyAdmin\DatabaseInterface;
  10. use PhpMyAdmin\Message;
  11. use PhpMyAdmin\Plugins;
  12. use PhpMyAdmin\Plugins\SchemaPlugin;
  13. use PhpMyAdmin\Relation;
  14. use PhpMyAdmin\Template;
  15. use PhpMyAdmin\Util;
  16. /**
  17. * Set of functions related to database designer
  18. *
  19. * @package PhpMyAdmin
  20. */
  21. class Designer
  22. {
  23. /**
  24. * @var Relation $relation
  25. */
  26. private $relation;
  27. /**
  28. * Constructor
  29. */
  30. public function __construct()
  31. {
  32. $this->relation = new Relation();
  33. }
  34. /**
  35. * Function to get html for displaying the page edit/delete form
  36. *
  37. * @param string $db database name
  38. * @param string $operation 'edit' or 'delete' depending on the operation
  39. *
  40. * @return string html content
  41. */
  42. public function getHtmlForEditOrDeletePages($db, $operation)
  43. {
  44. $cfgRelation = $this->relation->getRelationsParam();
  45. return Template::get('database/designer/edit_delete_pages')->render([
  46. 'db' => $db,
  47. 'operation' => $operation,
  48. 'pdfwork' => $cfgRelation['pdfwork'],
  49. 'pages' => $this->getPageIdsAndNames($db),
  50. ]);
  51. }
  52. /**
  53. * Function to get html for displaying the page save as form
  54. *
  55. * @param string $db database name
  56. *
  57. * @return string html content
  58. */
  59. public function getHtmlForPageSaveAs($db)
  60. {
  61. $cfgRelation = $this->relation->getRelationsParam();
  62. return Template::get('database/designer/page_save_as')->render([
  63. 'db' => $db,
  64. 'pdfwork' => $cfgRelation['pdfwork'],
  65. 'pages' => $this->getPageIdsAndNames($db),
  66. ]);
  67. }
  68. /**
  69. * Retrieve IDs and names of schema pages
  70. *
  71. * @param string $db database name
  72. *
  73. * @return array array of schema page id and names
  74. */
  75. private function getPageIdsAndNames($db)
  76. {
  77. $cfgRelation = $this->relation->getRelationsParam();
  78. $page_query = "SELECT `page_nr`, `page_descr` FROM "
  79. . Util::backquote($cfgRelation['db']) . "."
  80. . Util::backquote($cfgRelation['pdf_pages'])
  81. . " WHERE db_name = '" . $GLOBALS['dbi']->escapeString($db) . "'"
  82. . " ORDER BY `page_descr`";
  83. $page_rs = $this->relation->queryAsControlUser(
  84. $page_query,
  85. false,
  86. DatabaseInterface::QUERY_STORE
  87. );
  88. $result = [];
  89. while ($curr_page = $GLOBALS['dbi']->fetchAssoc($page_rs)) {
  90. $result[intval($curr_page['page_nr'])] = $curr_page['page_descr'];
  91. }
  92. return $result;
  93. }
  94. /**
  95. * Function to get html for displaying the schema export
  96. *
  97. * @param string $db database name
  98. * @param int $page the page to be exported
  99. *
  100. * @return string
  101. */
  102. public function getHtmlForSchemaExport($db, $page)
  103. {
  104. /* Scan for schema plugins */
  105. /* @var $export_list SchemaPlugin[] */
  106. $export_list = Plugins::getPlugins(
  107. "schema",
  108. 'libraries/classes/Plugins/Schema/',
  109. null
  110. );
  111. /* Fail if we didn't find any schema plugin */
  112. if (empty($export_list)) {
  113. return Message::error(
  114. __('Could not load schema plugins, please check your installation!')
  115. )->getDisplay();
  116. }
  117. return Template::get('database/designer/schema_export')
  118. ->render(
  119. [
  120. 'db' => $db,
  121. 'page' => $page,
  122. 'export_list' => $export_list
  123. ]
  124. );
  125. }
  126. /**
  127. * Returns HTML for including some variable to be accessed by JavaScript
  128. *
  129. * @param array $script_tables array on foreign key support for each table
  130. * @param array $script_contr initialization data array
  131. * @param array $script_display_field display fields of each table
  132. * @param int $display_page page number of the selected page
  133. *
  134. * @return string html
  135. */
  136. public function getHtmlForJsFields(
  137. array $script_tables,
  138. array $script_contr,
  139. array $script_display_field,
  140. $display_page
  141. ) {
  142. $cfgRelation = $this->relation->getRelationsParam();
  143. return Template::get('database/designer/js_fields')->render([
  144. 'server' => $GLOBALS['server'],
  145. 'db' => $_GET['db'],
  146. 'script_tables' => json_encode($script_tables),
  147. 'script_contr' => json_encode($script_contr),
  148. 'script_display_field' => json_encode($script_display_field),
  149. 'display_page' => $display_page,
  150. 'relation_pdfwork' => $cfgRelation['pdfwork'],
  151. ]);
  152. }
  153. /**
  154. * Returns HTML for the menu bar of the designer page
  155. *
  156. * @param boolean $visualBuilder whether this is visual query builder
  157. * @param string $selectedPage name of the selected page
  158. * @param array $paramsArray array with class name for various buttons
  159. * on side menu
  160. *
  161. * @return string html
  162. */
  163. public function getPageMenu($visualBuilder, $selectedPage, array $paramsArray)
  164. {
  165. return Template::get('database/designer/side_menu')->render([
  166. 'visual_builder' => $visualBuilder,
  167. 'selected_page' => $selectedPage,
  168. 'params_array' => $paramsArray,
  169. 'theme' => $GLOBALS['PMA_Theme'],
  170. ]);
  171. }
  172. /**
  173. * Returns array of stored values of Designer Settings
  174. *
  175. * @return array stored values
  176. */
  177. private function getSideMenuParamsArray()
  178. {
  179. $params = [];
  180. $cfgRelation = $this->relation->getRelationsParam();
  181. if ($GLOBALS['cfgRelation']['designersettingswork']) {
  182. $query = 'SELECT `settings_data` FROM '
  183. . Util::backquote($cfgRelation['db']) . '.'
  184. . Util::backquote($cfgRelation['designer_settings'])
  185. . ' WHERE ' . Util::backquote('username') . ' = "'
  186. . $GLOBALS['cfg']['Server']['user'] . '";';
  187. $result = $GLOBALS['dbi']->fetchSingleRow($query);
  188. $params = json_decode($result['settings_data'], true);
  189. }
  190. return $params;
  191. }
  192. /**
  193. * Returns class names for various buttons on Designer Side Menu
  194. *
  195. * @return array class names of various buttons
  196. */
  197. public function returnClassNamesFromMenuButtons()
  198. {
  199. $classes_array = [];
  200. $params_array = $this->getSideMenuParamsArray();
  201. if (isset($params_array['angular_direct'])
  202. && $params_array['angular_direct'] == 'angular'
  203. ) {
  204. $classes_array['angular_direct'] = 'M_butt_Selected_down';
  205. } else {
  206. $classes_array['angular_direct'] = 'M_butt';
  207. }
  208. if (isset($params_array['snap_to_grid'])
  209. && $params_array['snap_to_grid'] == 'on'
  210. ) {
  211. $classes_array['snap_to_grid'] = 'M_butt_Selected_down';
  212. } else {
  213. $classes_array['snap_to_grid'] = 'M_butt';
  214. }
  215. if (isset($params_array['pin_text'])
  216. && $params_array['pin_text'] == 'true'
  217. ) {
  218. $classes_array['pin_text'] = 'M_butt_Selected_down';
  219. } else {
  220. $classes_array['pin_text'] = 'M_butt';
  221. }
  222. if (isset($params_array['relation_lines'])
  223. && $params_array['relation_lines'] == 'false'
  224. ) {
  225. $classes_array['relation_lines'] = 'M_butt_Selected_down';
  226. } else {
  227. $classes_array['relation_lines'] = 'M_butt';
  228. }
  229. if (isset($params_array['small_big_all'])
  230. && $params_array['small_big_all'] == 'v'
  231. ) {
  232. $classes_array['small_big_all'] = 'M_butt_Selected_down';
  233. } else {
  234. $classes_array['small_big_all'] = 'M_butt';
  235. }
  236. if (isset($params_array['side_menu'])
  237. && $params_array['side_menu'] == 'true'
  238. ) {
  239. $classes_array['side_menu'] = 'M_butt_Selected_down';
  240. } else {
  241. $classes_array['side_menu'] = 'M_butt';
  242. }
  243. return $classes_array;
  244. }
  245. /**
  246. * Returns HTML for the canvas element
  247. *
  248. * @return string html
  249. */
  250. public function getHtmlCanvas()
  251. {
  252. return Template::get('database/designer/canvas')->render();
  253. }
  254. /**
  255. * Return HTML for the table list
  256. *
  257. * @param array $tab_pos table positions
  258. * @param int $display_page page number of the selected page
  259. *
  260. * @return string html
  261. */
  262. public function getHtmlTableList(array $tab_pos, $display_page)
  263. {
  264. return Template::get('database/designer/table_list')->render([
  265. 'tab_pos' => $tab_pos,
  266. 'display_page' => $display_page,
  267. 'theme' => $GLOBALS['PMA_Theme'],
  268. 'table_names' => $GLOBALS['designer']['TABLE_NAME'],
  269. 'table_names_url' => $GLOBALS['designer_url']['TABLE_NAME'],
  270. 'table_names_small_url' => $GLOBALS['designer_url']['TABLE_NAME_SMALL'],
  271. 'table_names_out' => $GLOBALS['designer_out']['TABLE_NAME'],
  272. ]);
  273. }
  274. /**
  275. * Get HTML to display tables on designer page
  276. *
  277. * @param array $tab_pos tables positions
  278. * @param int $display_page page number of the selected page
  279. * @param array $tab_column table column info
  280. * @param array $tables_all_keys all indices
  281. * @param array $tables_pk_or_unique_keys unique or primary indices
  282. *
  283. * @return string html
  284. */
  285. public function getDatabaseTables(
  286. array $tab_pos,
  287. $display_page,
  288. array $tab_column,
  289. array $tables_all_keys,
  290. array $tables_pk_or_unique_keys
  291. ) {
  292. return Template::get('database/designer/database_tables')->render([
  293. 'db' => $GLOBALS['db'],
  294. 'get_db' => $_GET['db'],
  295. 'has_query' => isset($_REQUEST['query']),
  296. 'tab_pos' => $tab_pos,
  297. 'display_page' => $display_page,
  298. 'tab_column' => $tab_column,
  299. 'tables_all_keys' => $tables_all_keys,
  300. 'tables_pk_or_unique_keys' => $tables_pk_or_unique_keys,
  301. 'table_names' => $GLOBALS['designer']['TABLE_NAME'],
  302. 'table_names_url' => $GLOBALS['designer_url']['TABLE_NAME'],
  303. 'table_names_small' => $GLOBALS['designer']['TABLE_NAME_SMALL'],
  304. 'table_names_small_url' => $GLOBALS['designer_url']['TABLE_NAME_SMALL'],
  305. 'table_names_small_out' => $GLOBALS['designer_out']['TABLE_NAME_SMALL'],
  306. 'table_types' => $GLOBALS['designer']['TABLE_TYPE'],
  307. 'owner_out' => $GLOBALS['designer_out']['OWNER'],
  308. 'theme' => $GLOBALS['PMA_Theme'],
  309. ]);
  310. }
  311. /**
  312. * Returns HTML for the new relations panel.
  313. *
  314. * @return string html
  315. */
  316. public function getNewRelationPanel()
  317. {
  318. return Template::get('database/designer/new_relation_panel')
  319. ->render();
  320. }
  321. /**
  322. * Returns HTML for the relations delete panel
  323. *
  324. * @return string html
  325. */
  326. public function getDeleteRelationPanel()
  327. {
  328. return Template::get('database/designer/delete_relation_panel')
  329. ->render();
  330. }
  331. /**
  332. * Returns HTML for the options panel
  333. *
  334. * @return string html
  335. */
  336. public function getOptionsPanel()
  337. {
  338. return Template::get('database/designer/options_panel')->render();
  339. }
  340. /**
  341. * Get HTML for the 'rename to' panel
  342. *
  343. * @return string html
  344. */
  345. public function getRenameToPanel()
  346. {
  347. return Template::get('database/designer/rename_to_panel')
  348. ->render();
  349. }
  350. /**
  351. * Returns HTML for the 'having' panel
  352. *
  353. * @return string html
  354. */
  355. public function getHavingQueryPanel()
  356. {
  357. return Template::get('database/designer/having_query_panel')
  358. ->render();
  359. }
  360. /**
  361. * Returns HTML for the 'aggregate' panel
  362. *
  363. * @return string html
  364. */
  365. public function getAggregateQueryPanel()
  366. {
  367. return Template::get('database/designer/aggregate_query_panel')
  368. ->render();
  369. }
  370. /**
  371. * Returns HTML for the 'where' panel
  372. *
  373. * @return string html
  374. */
  375. public function getWhereQueryPanel()
  376. {
  377. return Template::get('database/designer/where_query_panel')
  378. ->render();
  379. }
  380. /**
  381. * Returns HTML for the query details panel
  382. *
  383. * @param string $db Database name
  384. *
  385. * @return string html
  386. */
  387. public function getQueryDetails($db)
  388. {
  389. return Template::get('database/designer/query_details')->render([
  390. 'db' => $db,
  391. ]);
  392. }
  393. }