User_Schema.class.php 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Schema support library
  5. *
  6. * @package PhpMyAdmin-schema
  7. */
  8. if (! defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. /**
  12. * This Class interacts with the user to gather the information
  13. * about their tables for which they want to export the relational schema
  14. * export options are shown to user from they can choose
  15. *
  16. * @package PhpMyAdmin-schema
  17. */
  18. class PMA_User_Schema
  19. {
  20. public $chosenPage;
  21. public $autoLayoutForeign;
  22. public $autoLayoutInternal;
  23. public $pageNumber;
  24. public $c_table_rows;
  25. public $action;
  26. /**
  27. * Sets action to be performed with schema.
  28. *
  29. * @param string $value action name
  30. *
  31. * @return void
  32. */
  33. public function setAction($value)
  34. {
  35. $this->action = $value;
  36. }
  37. /**
  38. * This function will process the user defined pages
  39. * and tables which will be exported as Relational schema
  40. * you can set the table positions on the paper via scratchboard
  41. * for table positions, put the x,y co-ordinates
  42. *
  43. * $this->action tells what the Schema is supposed to do
  44. * create and select a page, generate schema etc
  45. *
  46. * @access public
  47. * @return void
  48. */
  49. public function processUserChoice()
  50. {
  51. global $db, $cfgRelation;
  52. if (isset($this->action)) {
  53. switch ($this->action) {
  54. case 'selectpage':
  55. $this->chosenPage = $_REQUEST['chpage'];
  56. if ('1' == $_REQUEST['action_choose']) {
  57. $this->deleteCoordinates(
  58. $db,
  59. $cfgRelation,
  60. $this->chosenPage
  61. );
  62. $this->deletePages(
  63. $db,
  64. $cfgRelation,
  65. $this->chosenPage
  66. );
  67. $this->chosenPage = 0;
  68. }
  69. break;
  70. case 'createpage':
  71. $this->pageNumber = PMA_REL_createPage(
  72. $_POST['newpage'],
  73. $cfgRelation,
  74. $db
  75. );
  76. $this->autoLayoutForeign = isset($_POST['auto_layout_foreign'])
  77. ? "1"
  78. : null;
  79. $this->autoLayoutInternal = isset($_POST['auto_layout_internal'])
  80. ? "1"
  81. : null;
  82. $this->processRelations(
  83. $db,
  84. $this->pageNumber,
  85. $cfgRelation
  86. );
  87. break;
  88. case 'edcoord':
  89. $this->chosenPage = $_POST['chpage'];
  90. $this->c_table_rows = $_POST['c_table_rows'];
  91. $this->_editCoordinates($db, $cfgRelation);
  92. break;
  93. case 'delete_old_references':
  94. $this->_deleteTableRows(
  95. $_POST['delrow'],
  96. $cfgRelation,
  97. $db,
  98. $_POST['chpage']
  99. );
  100. break;
  101. case 'process_export':
  102. $this->_processExportSchema();
  103. break;
  104. } // end switch
  105. } // end if (isset($do))
  106. }
  107. /**
  108. * shows/displays the HTML FORM to create the page
  109. *
  110. * @param string $db name of the selected database
  111. *
  112. * @return void
  113. * @access public
  114. */
  115. public function showCreatePageDialog($db)
  116. {
  117. ?>
  118. <form method="post" action="schema_edit.php" name="frm_create_page">
  119. <fieldset>
  120. <legend>
  121. <?php echo __('Create a page') . "\n"; ?>
  122. </legend>
  123. <?php echo PMA_generate_common_hidden_inputs($db); ?>
  124. <input type="hidden" name="do" value="createpage" />
  125. <table>
  126. <tr>
  127. <td><label for="id_newpage"><?php echo __('Page name'); ?></label></td>
  128. <td>
  129. <input type="text" name="newpage" id="id_newpage" size="20" maxlength="50" />
  130. </td>
  131. </tr>
  132. <tr>
  133. <td><?php echo __('Automatic layout based on'); ?></td>
  134. <td>
  135. <input type="checkbox" name="auto_layout_internal" id="id_auto_layout_internal" /><label for="id_auto_layout_internal">
  136. <?php echo __('Internal relations'); ?></label><br />
  137. <?php
  138. /*
  139. * Check to see whether INNODB and PBXT storage engines
  140. * are Available in MYSQL PACKAGE
  141. * If available, then provide AutoLayout for Foreign Keys in Schema View
  142. */
  143. if (PMA_StorageEngine::isValid('InnoDB') || PMA_StorageEngine::isValid('PBXT')) {
  144. ?>
  145. <input type="checkbox" name="auto_layout_foreign" id="id_auto_layout_foreign" /><label for="id_auto_layout_foreign">
  146. <?php echo __('FOREIGN KEY'); ?></label><br />
  147. <?php
  148. }
  149. ?>
  150. </td></tr>
  151. </table>
  152. </fieldset>
  153. <fieldset class="tblFooters">
  154. <input type="submit" value="<?php echo __('Go'); ?>" />
  155. </fieldset>
  156. </form>
  157. <?php
  158. }
  159. /**
  160. * shows/displays the created page names in a drop down list
  161. * User can select any page number and edit it using dashboard etc
  162. *
  163. * @return void
  164. * @access public
  165. */
  166. public function selectPage()
  167. {
  168. global $db,$table,$cfgRelation;
  169. $page_query = 'SELECT * FROM '
  170. . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
  171. . PMA_Util::backquote($cfgRelation['pdf_pages'])
  172. . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
  173. $page_rs = PMA_queryAsControlUser(
  174. $page_query, false, PMA_DBI_QUERY_STORE
  175. );
  176. if ($page_rs && PMA_DBI_num_rows($page_rs) > 0) {
  177. ?>
  178. <form method="get" action="schema_edit.php" name="frm_select_page">
  179. <fieldset>
  180. <legend>
  181. <?php echo __('Please choose a page to edit') . "\n"; ?>
  182. </legend>
  183. <?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
  184. <input type="hidden" name="do" value="selectpage" />
  185. <select name="chpage" id="chpage" class="autosubmit">
  186. <option value="0"><?php echo __('Select page'); ?></option>
  187. <?php
  188. while ($curr_page = PMA_DBI_fetch_assoc($page_rs)) {
  189. $page_nr = intval($curr_page['page_nr']);
  190. echo "\n" . ' '
  191. . '<option value="' . $page_nr . '"';
  192. if (isset($this->chosenPage) && $this->chosenPage == page_nr) {
  193. echo ' selected="selected"';
  194. }
  195. echo '>' . $page_nr . ': '
  196. . htmlspecialchars($curr_page['page_descr']) . '</option>';
  197. } // end while
  198. echo "\n";
  199. ?>
  200. </select>
  201. <?php
  202. $choices = array(
  203. '0' => __('Edit'),
  204. '1' => __('Delete')
  205. );
  206. echo PMA_Util::getRadioFields(
  207. 'action_choose', $choices, '0', false
  208. );
  209. unset($choices);
  210. ?>
  211. </fieldset>
  212. <fieldset class="tblFooters">
  213. <input type="submit" value="<?php echo __('Go'); ?>" /><br />
  214. </fieldset>
  215. </form>
  216. <?php
  217. } // end IF
  218. echo "\n";
  219. } // end function
  220. /**
  221. * A dashboard is displayed to AutoLayout the position of tables
  222. * users can drag n drop the tables and change their positions
  223. *
  224. * @return void
  225. * @access public
  226. */
  227. public function showTableDashBoard()
  228. {
  229. global $db, $cfgRelation, $table, $with_field_names;
  230. /*
  231. * We will need an array of all tables in this db
  232. */
  233. $selectboxall = array('--');
  234. $alltab_rs = PMA_DBI_query(
  235. 'SHOW TABLES FROM ' . PMA_Util::backquote($db) . ';',
  236. null,
  237. PMA_DBI_QUERY_STORE
  238. );
  239. while ($val = @PMA_DBI_fetch_row($alltab_rs)) {
  240. $selectboxall[] = $val[0];
  241. }
  242. $tabExist = array();
  243. /*
  244. * Now if we already have chosen a page number then we should
  245. * show the tables involved
  246. */
  247. if (isset($this->chosenPage) && $this->chosenPage > 0) {
  248. echo "\n";
  249. echo "<h2>" . __('Select Tables') . "</h2>";
  250. $page_query = 'SELECT * FROM '
  251. . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
  252. . '.' . PMA_Util::backquote($cfgRelation['table_coords'])
  253. . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
  254. . ' AND pdf_page_number = \''
  255. . PMA_Util::sqlAddSlashes($this->chosenPage) . '\'';
  256. $page_rs = PMA_queryAsControlUser($page_query, false);
  257. $array_sh_page = array();
  258. while ($temp_sh_page = @PMA_DBI_fetch_assoc($page_rs)) {
  259. $array_sh_page[] = $temp_sh_page;
  260. }
  261. /*
  262. * Display WYSIWYG parts
  263. */
  264. if (! isset($_POST['with_field_names'])
  265. && ! isset($_POST['showwysiwyg'])
  266. ) {
  267. $with_field_names = true;
  268. } elseif (isset($_POST['with_field_names'])) {
  269. $with_field_names = true;
  270. }
  271. $this->_displayScratchboardTables($array_sh_page);
  272. echo '<form method="post" action="schema_edit.php" name="edcoord">';
  273. echo PMA_generate_common_hidden_inputs($db, $table);
  274. echo '<input type="hidden" name="chpage" '
  275. . 'value="' . htmlspecialchars($this->chosenPage) . '" />';
  276. echo '<input type="hidden" name="do" value="edcoord" />';
  277. echo '<table>';
  278. echo '<tr>';
  279. echo '<th>' . __('Table') . '</th>';
  280. echo '<th>' . __('Delete') . '</th>';
  281. echo '<th>X</th>';
  282. echo '<th>Y</th>';
  283. echo '</tr>';
  284. if (isset($ctable)) {
  285. unset($ctable);
  286. }
  287. /*
  288. * Add one more empty row
  289. */
  290. $array_sh_page[] = array(
  291. 'table_name' => '',
  292. 'x' => '0',
  293. 'y' => '0',
  294. );
  295. $i = 0;
  296. $odd_row = true;
  297. foreach ($array_sh_page as $sh_page) {
  298. $_mtab = $sh_page['table_name'];
  299. if (! empty($_mtab)) {
  300. $tabExist[$_mtab] = false;
  301. }
  302. echo '<tr class="noclick ';
  303. if ($odd_row) {
  304. echo 'odd';
  305. } else {
  306. echo 'even';
  307. }
  308. echo '">';
  309. $odd_row = !$odd_row;
  310. echo '<td>';
  311. echo '<select name="c_table_' . $i . '[name]">';
  312. foreach ($selectboxall as $value) {
  313. echo '<option value="' . htmlspecialchars($value) . '"';
  314. if (! empty($_mtab) && $value == $_mtab) {
  315. echo ' selected="selected"';
  316. $tabExist[$_mtab] = true;
  317. }
  318. echo '>' . htmlspecialchars($value) . '</option>';
  319. }
  320. echo '</select>';
  321. echo '</td>';
  322. echo '<td>';
  323. echo '<input type="checkbox" id="id_c_table_' . $i .'" '
  324. . 'name="c_table_' . $i . '[delete]" value="y" />';
  325. echo '<label for="id_c_table_' . $i .'">'
  326. . __('Delete') . '</label>';
  327. echo '</td>';
  328. echo '<td>';
  329. echo '<input type="text" class="position-change" data-axis="left" '
  330. . 'data-number="' . $i . '" id="c_table_' . $i . '_x" '
  331. . 'name="c_table_' . $i . '[x]" value="'
  332. . $sh_page['x'] . '" />';
  333. echo '</td>';
  334. echo '<td>';
  335. echo '<input type="text" class="position-change" data-axis="top" '
  336. . 'data-number="' . $i . '" id="c_table_' . $i . '_y" '
  337. . 'name="c_table_' . $i . '[y]" value="'
  338. . $sh_page['y'] . '" />';
  339. echo '</td>';
  340. echo '</tr>';
  341. $i++;
  342. }
  343. echo '</table>';
  344. echo '<input type="hidden" name="c_table_rows" value="' . $i . '" />';
  345. echo '<input type="hidden" id="showwysiwyg" name="showwysiwyg" value="'
  346. . ((isset($showwysiwyg) && $showwysiwyg == '1') ? '1' : '0')
  347. . '" />';
  348. echo '<input type="checkbox" id="id_with_field_names" '
  349. . 'name="with_field_names" '
  350. . (isset($with_field_names) ? 'checked="checked"' : ''). ' />';
  351. echo '<label for="id_with_field_names">'
  352. . __('Column names') . '</label><br />';
  353. echo '<input type="submit" value="' . __('Save') . '" />';
  354. echo '</form>' . "\n\n";
  355. } // end if
  356. if (isset($tabExist)) {
  357. $this->_deleteTables($db, $this->chosenPage, $tabExist);
  358. }
  359. }
  360. /**
  361. * show Export relational schema generation options
  362. * user can select export type of his own choice
  363. * and the attributes related to it
  364. *
  365. * @return void
  366. * @access public
  367. */
  368. public function displaySchemaGenerationOptions()
  369. {
  370. global $cfg,$db,$test_rs,$chpage;
  371. ?>
  372. <form method="post" action="schema_export.php" class="disableAjax">
  373. <fieldset>
  374. <legend>
  375. <?php
  376. echo PMA_generate_common_hidden_inputs($db);
  377. if (in_array(
  378. $GLOBALS['cfg']['ActionLinksMode'],
  379. array('icons', 'both')
  380. )
  381. ) {
  382. echo PMA_Util::getImage('b_views.png');
  383. }
  384. echo __('Display relational schema');
  385. ?>:
  386. </legend>
  387. <select name="export_type" id="export_type">
  388. <option value="pdf" selected="selected">PDF</option>
  389. <option value="svg">SVG</option>
  390. <option value="dia">DIA</option>
  391. <option value="eps">EPS</option>
  392. </select>
  393. <label><?php echo __('Select Export Relational Type');?></label><br />
  394. <?php
  395. if (isset($test_rs)) {
  396. ?>
  397. <label for="pdf_page_number_opt"><?php echo __('Page number:'); ?></label>
  398. <select name="pdf_page_number" id="pdf_page_number_opt">
  399. <?php
  400. while ($pages = @PMA_DBI_fetch_assoc($test_rs)) {
  401. $page_nr = intval($pages['page_nr']);
  402. echo ' <option value="' . $page_nr . '">'
  403. . $page_nr . ': ' . htmlspecialchars($pages['page_descr']) . '</option>' . "\n";
  404. } // end while
  405. PMA_DBI_free_result($test_rs);
  406. unset($test_rs);
  407. ?>
  408. </select><br />
  409. <?php
  410. } else {
  411. ?>
  412. <input type="hidden" name="pdf_page_number" value="<?php echo htmlspecialchars($this->chosenPage); ?>" />
  413. <?php
  414. }
  415. ?>
  416. <input type="hidden" name="do" value="process_export" />
  417. <input type="hidden" name="chpage" value="<?php echo $chpage; ?>" />
  418. <input type="checkbox" name="show_grid" id="show_grid_opt" />
  419. <label for="show_grid_opt"><?php echo __('Show grid'); ?></label><br />
  420. <input type="checkbox" name="show_color" id="show_color_opt" checked="checked" />
  421. <label for="show_color_opt"><?php echo __('Show color'); ?></label>
  422. <br />
  423. <input type="checkbox" name="show_table_dimension" id="show_table_dim_opt" />
  424. <label for="show_table_dim_opt">
  425. <?php echo __('Show dimension of tables'); ?>
  426. </label><br />
  427. <input type="checkbox" name="all_tables_same_width" id="all_tables_same_width" />
  428. <label for="all_tables_same_width">
  429. <?php echo __('Display all tables with the same width'); ?>
  430. </label><br />
  431. <input type="checkbox" name="with_doc" id="with_doc" checked="checked" />
  432. <label for="with_doc"><?php echo __('Data Dictionary'); ?></label><br />
  433. <input type="checkbox" name="show_keys" id="show_keys" />
  434. <label for="show_keys"><?php echo __('Only show keys'); ?></label><br />
  435. <select name="orientation" id="orientation_opt" class="paper-change">
  436. <option value="L"><?php echo __('Landscape');?></option>
  437. <option value="P"><?php echo __('Portrait');?></option>
  438. </select>
  439. <label for="orientation_opt"><?php echo __('Orientation'); ?></label>
  440. <br />
  441. <select name="paper" id="paper_opt" class="paper-change">
  442. <?php
  443. foreach ($cfg['PDFPageSizes'] as $val) {
  444. echo '<option value="' . $val . '"';
  445. if ($val == $cfg['PDFDefaultPageSize']) {
  446. echo ' selected="selected"';
  447. }
  448. echo ' >' . $val . '</option>' . "\n";
  449. }
  450. ?>
  451. </select>
  452. <label for="paper_opt"><?php echo __('Paper size'); ?></label>
  453. </fieldset>
  454. <fieldset class="tblFooters">
  455. <input type="submit" value="<?php echo __('Go'); ?>" />
  456. </fieldset>
  457. </form>
  458. <?php
  459. }
  460. /**
  461. * Check if there are tables that need to be deleted in dashboard,
  462. * if there are, ask the user for allowance
  463. *
  464. * @param string $db name of database selected
  465. * @param integer $chpage selected page
  466. * @param array $tabExist array of booleans
  467. *
  468. * @return void
  469. * @access private
  470. */
  471. private function _deleteTables($db, $chpage, $tabExist)
  472. {
  473. $_strtrans = '';
  474. $_strname = '';
  475. $shoot = false;
  476. if (empty($tabExist) || ! is_array($tabExist)) {
  477. return;
  478. }
  479. foreach ($tabExist as $key => $value) {
  480. if (! $value) {
  481. $_strtrans .= '<input type="hidden" name="delrow[]" value="'
  482. . htmlspecialchars($key) . '" />' . "\n";
  483. $_strname .= '<li>' . htmlspecialchars($key) . '</li>' . "\n";
  484. $shoot = true;
  485. }
  486. }
  487. if (!$shoot) {
  488. return;
  489. }
  490. echo '<br /><form action="schema_edit.php" method="post">' . "\n"
  491. . PMA_generate_common_hidden_inputs($db)
  492. . '<input type="hidden" name="do" value="delete_old_references" />'
  493. . "\n"
  494. . '<input type="hidden" name="chpage" value="'
  495. . htmlspecialchars($chpage) . '" />' . "\n"
  496. . __(
  497. 'The current page has references to tables that no longer exist.'
  498. . ' Would you like to delete those references?'
  499. )
  500. . '<ul>' . "\n"
  501. . $_strname
  502. . '</ul>' . "\n"
  503. . $_strtrans
  504. . '<input type="submit" value="' . __('Go') . '" />' . "\n"
  505. . '</form>';
  506. }
  507. /**
  508. * Check if there are tables that need to be deleted in dashboard,
  509. * if there are, ask the user for allowance
  510. *
  511. * @param array $array_sh_page array of tables on page
  512. *
  513. * @return void
  514. * @access private
  515. */
  516. private function _displayScratchboardTables($array_sh_page)
  517. {
  518. global $with_field_names, $db;
  519. echo '<form method="post" action="schema_edit.php" name="dragdrop">';
  520. echo '<input type="button" name="dragdrop" id="toggle-dragdrop" '
  521. . 'value="' . __('Toggle scratchboard') . '" />';
  522. echo '<input type="button" name="dragdropreset" id="reset-dragdrop" '
  523. . 'value="' . __('Reset') . '" />';
  524. echo '</form>';
  525. echo '<div id="pdflayout" class="pdflayout" style="visibility: hidden;">';
  526. $i = 0;
  527. foreach ($array_sh_page as $temp_sh_page) {
  528. $drag_x = $temp_sh_page['x'];
  529. $drag_y = $temp_sh_page['y'];
  530. echo '<div id="table_' . $i . '" '
  531. . 'data-number="' . $i .'" '
  532. . 'data-x="' . $drag_x . '" '
  533. . 'data-y="' . $drag_y . '" '
  534. . 'class="pdflayout_table"'
  535. . '>'
  536. . '<u>'
  537. . htmlspecialchars($temp_sh_page['table_name'])
  538. . '</u>';
  539. if (isset($with_field_names)) {
  540. $fields = PMA_DBI_get_columns($db, $temp_sh_page['table_name']);
  541. // if the table has been dropped from outside phpMyAdmin,
  542. // we can no longer obtain its columns list
  543. if ($fields) {
  544. foreach ($fields as $row) {
  545. echo '<br />' . htmlspecialchars($row['Field']) . "\n";
  546. }
  547. }
  548. }
  549. echo '</div>' . "\n";
  550. $i++;
  551. }
  552. echo '</div>';
  553. }
  554. /**
  555. * delete the table rows with table co-ordinates
  556. *
  557. * @param int $delrow delete selected table from list of tables
  558. * @param array $cfgRelation relation settings
  559. * @param string $db database name
  560. * @param integer $chpage selected page for adding relations etc
  561. *
  562. * @return void
  563. * @access private
  564. */
  565. private function _deleteTableRows($delrow,$cfgRelation,$db,$chpage)
  566. {
  567. foreach ($delrow as $current_row) {
  568. $del_query = 'DELETE FROM '
  569. . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
  570. . PMA_Util::backquote($cfgRelation['table_coords']) . ' ' . "\n"
  571. . ' WHERE db_name = \''
  572. . PMA_Util::sqlAddSlashes($db) . '\'' . "\n"
  573. . ' AND table_name = \''
  574. . PMA_Util::sqlAddSlashes($current_row) . '\'' . "\n"
  575. . ' AND pdf_page_number = \''
  576. . PMA_Util::sqlAddSlashes($chpage) . '\'';
  577. PMA_queryAsControlUser($del_query, false);
  578. }
  579. }
  580. /**
  581. * get all the export options and verify
  582. * call and include the appropriate Schema Class depending on $export_type
  583. *
  584. * @return void
  585. * @access private
  586. */
  587. private function _processExportSchema()
  588. {
  589. /**
  590. * Settings for relation stuff
  591. */
  592. include_once './libraries/transformations.lib.php';
  593. include_once './libraries/Index.class.php';
  594. /**
  595. * default is PDF, otherwise validate it's only letters a-z
  596. */
  597. global $db,$export_type;
  598. if (!isset($export_type) || !preg_match('/^[a-zA-Z]+$/', $export_type)) {
  599. $export_type = 'pdf';
  600. }
  601. PMA_DBI_select_db($db);
  602. include "libraries/schema/" . ucfirst($export_type)
  603. . "_Relation_Schema.class.php";
  604. eval("new PMA_" . ucfirst($export_type) . "_Relation_Schema();");
  605. }
  606. /**
  607. * delete X and Y coordinates
  608. *
  609. * @param string $db The database name
  610. * @param array $cfgRelation relation settings
  611. * @param integer $choosePage selected page for adding relations etc
  612. *
  613. * @return void
  614. * @access private
  615. */
  616. public function deleteCoordinates($db, $cfgRelation, $choosePage)
  617. {
  618. $query = 'DELETE FROM '
  619. . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
  620. . PMA_Util::backquote($cfgRelation['table_coords'])
  621. . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
  622. . ' AND pdf_page_number = \''
  623. . PMA_Util::sqlAddSlashes($choosePage) . '\'';
  624. PMA_queryAsControlUser($query, false);
  625. }
  626. /**
  627. * delete pages
  628. *
  629. * @param string $db The database name
  630. * @param array $cfgRelation relation settings
  631. * @param integer $choosePage selected page for adding relations etc
  632. *
  633. * @return void
  634. * @access private
  635. */
  636. public function deletePages($db, $cfgRelation, $choosePage)
  637. {
  638. $query = 'DELETE FROM '
  639. . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
  640. . PMA_Util::backquote($cfgRelation['pdf_pages'])
  641. . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
  642. . ' AND page_nr = \'' . PMA_Util::sqlAddSlashes($choosePage) . '\'';
  643. PMA_queryAsControlUser($query, false);
  644. }
  645. /**
  646. * process internal and foreign key relations
  647. *
  648. * @param string $db The database name
  649. * @param integer $pageNumber document number/Id
  650. * @param array $cfgRelation relation settings
  651. *
  652. * @return void
  653. * @access private
  654. */
  655. public function processRelations($db, $pageNumber, $cfgRelation)
  656. {
  657. /*
  658. * A u t o m a t i c l a y o u t
  659. *
  660. * There are 2 kinds of relations in PMA
  661. * 1) Internal Relations 2) Foreign Key Relations
  662. */
  663. if (isset($this->autoLayoutInternal) || isset($this->autoLayoutForeign)) {
  664. $all_tables = array();
  665. }
  666. if (isset($this->autoLayoutForeign)) {
  667. /*
  668. * get the tables list
  669. * who support FOREIGN KEY, it's not
  670. * important that we group together InnoDB tables
  671. * and PBXT tables, as this logic is just to put
  672. * the tables on the layout, not to determine relations
  673. */
  674. $tables = PMA_DBI_get_tables_full($db);
  675. $foreignkey_tables = array();
  676. foreach ($tables as $table_name => $table_properties) {
  677. if (PMA_Util::isForeignKeySupported($table_properties['ENGINE'])) {
  678. $foreignkey_tables[] = $table_name;
  679. }
  680. }
  681. $all_tables = $foreignkey_tables;
  682. /*
  683. * could be improved by finding the tables which have the
  684. * most references keys and placing them at the beginning
  685. * of the array (so that they are all center of schema)
  686. */
  687. unset($tables, $foreignkey_tables);
  688. }
  689. if (isset($this->autoLayoutInternal)) {
  690. /*
  691. * get the tables list who support Internal Relations;
  692. * This type of relations will be created when
  693. * you setup the PMA tables correctly
  694. */
  695. $master_tables = 'SELECT COUNT(master_table), master_table'
  696. . ' FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
  697. . PMA_Util::backquote($cfgRelation['relation'])
  698. . ' WHERE master_db = \'' . PMA_Util::sqlAddSlashes($db) . '\''
  699. . ' GROUP BY master_table'
  700. . ' ORDER BY COUNT(master_table) DESC';
  701. $master_tables_rs = PMA_queryAsControlUser(
  702. $master_tables, false, PMA_DBI_QUERY_STORE
  703. );
  704. if ($master_tables_rs && PMA_DBI_num_rows($master_tables_rs) > 0) {
  705. /* first put all the master tables at beginning
  706. * of the list, so they are near the center of
  707. * the schema
  708. */
  709. while (list(, $master_table) = PMA_DBI_fetch_row($master_tables_rs)) {
  710. $all_tables[] = $master_table;
  711. }
  712. /* Now for each master, add its foreigns into an array
  713. * of foreign tables, if not already there
  714. * (a foreign might be foreign for more than
  715. * one table, and might be a master itself)
  716. */
  717. $foreign_tables = array();
  718. foreach ($all_tables as $master_table) {
  719. $foreigners = PMA_getForeigners($db, $master_table);
  720. foreach ($foreigners as $foreigner) {
  721. if (! in_array($foreigner['foreign_table'], $foreign_tables)) {
  722. $foreign_tables[] = $foreigner['foreign_table'];
  723. }
  724. }
  725. }
  726. /*
  727. * Now merge the master and foreign arrays/tables
  728. */
  729. foreach ($foreign_tables as $foreign_table) {
  730. if (! in_array($foreign_table, $all_tables)) {
  731. $all_tables[] = $foreign_table;
  732. }
  733. }
  734. }
  735. }
  736. if (isset($this->autoLayoutInternal) || isset($this->autoLayoutForeign)) {
  737. $this->addRelationCoordinates(
  738. $all_tables, $pageNumber, $db, $cfgRelation
  739. );
  740. }
  741. $this->chosenPage = $pageNumber;
  742. }
  743. /**
  744. * Add X and Y coordinates for a table
  745. *
  746. * @param array $all_tables A list of all tables involved
  747. * @param integer $pageNumber document number/Id
  748. * @param string $db The database name
  749. * @param array $cfgRelation relation settings
  750. *
  751. * @return void
  752. * @access private
  753. */
  754. public function addRelationCoordinates(
  755. $all_tables, $pageNumber, $db, $cfgRelation
  756. ) {
  757. /*
  758. * Now generate the coordinates for the schema
  759. * in a clockwise spiral and add to co-ordinates table
  760. */
  761. $pos_x = 300;
  762. $pos_y = 300;
  763. $delta = 110;
  764. $delta_mult = 1.10;
  765. $direction = "right";
  766. foreach ($all_tables as $current_table) {
  767. /*
  768. * save current table's coordinates
  769. */
  770. $insert_query = 'INSERT INTO '
  771. . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
  772. . PMA_Util::backquote($cfgRelation['table_coords']) . ' '
  773. . '(db_name, table_name, pdf_page_number, x, y) '
  774. . 'VALUES (\'' . PMA_Util::sqlAddSlashes($db) . '\', \''
  775. . PMA_Util::sqlAddSlashes($current_table) . '\',' . $pageNumber
  776. . ',' . $pos_x . ',' . $pos_y . ')';
  777. PMA_queryAsControlUser($insert_query, false);
  778. /*
  779. * compute for the next table
  780. */
  781. switch ($direction) {
  782. case 'right':
  783. $pos_x += $delta;
  784. $direction = "down";
  785. $delta *= $delta_mult;
  786. break;
  787. case 'down':
  788. $pos_y += $delta;
  789. $direction = "left";
  790. $delta *= $delta_mult;
  791. break;
  792. case 'left':
  793. $pos_x -= $delta;
  794. $direction = "up";
  795. $delta *= $delta_mult;
  796. break;
  797. case 'up':
  798. $pos_y -= $delta;
  799. $direction = "right";
  800. $delta *= $delta_mult;
  801. break;
  802. }
  803. }
  804. }
  805. /**
  806. * update X and Y coordinates for a table
  807. *
  808. * @param string $db The database name
  809. * @param array $cfgRelation relation settings
  810. *
  811. * @return void
  812. * @access private
  813. */
  814. private function _editCoordinates($db, $cfgRelation)
  815. {
  816. for ($i = 0; $i < $this->c_table_rows; $i++) {
  817. $arrvalue = $_POST['c_table_' . $i];
  818. if (! isset($arrvalue['x']) || $arrvalue['x'] == '') {
  819. $arrvalue['x'] = 0;
  820. }
  821. if (! isset($arrvalue['y']) || $arrvalue['y'] == '') {
  822. $arrvalue['y'] = 0;
  823. }
  824. if (isset($arrvalue['name']) && $arrvalue['name'] != '--') {
  825. $test_query = 'SELECT * FROM '
  826. . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
  827. . PMA_Util::backquote($cfgRelation['table_coords'])
  828. . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
  829. . ' AND table_name = \''
  830. . PMA_Util::sqlAddSlashes($arrvalue['name']) . '\''
  831. . ' AND pdf_page_number = \''
  832. . PMA_Util::sqlAddSlashes($this->chosenPage) . '\'';
  833. $test_rs = PMA_queryAsControlUser(
  834. $test_query, false, PMA_DBI_QUERY_STORE
  835. );
  836. //echo $test_query;
  837. if ($test_rs && PMA_DBI_num_rows($test_rs) > 0) {
  838. if (isset($arrvalue['delete']) && $arrvalue['delete'] == 'y') {
  839. $ch_query = 'DELETE FROM '
  840. . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
  841. . '.'
  842. . PMA_Util::backquote($cfgRelation['table_coords'])
  843. . ' WHERE db_name = \''
  844. . PMA_Util::sqlAddSlashes($db) . '\''
  845. . ' AND table_name = \''
  846. . PMA_Util::sqlAddSlashes($arrvalue['name']) . '\''
  847. . ' AND pdf_page_number = \''
  848. . PMA_Util::sqlAddSlashes($this->chosenPage) . '\'';
  849. } else {
  850. $ch_query = 'UPDATE '
  851. . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
  852. . '.' . PMA_Util::backquote($cfgRelation['table_coords'])
  853. . ' '
  854. . 'SET x = ' . $arrvalue['x'] . ', y= ' . $arrvalue['y']
  855. . ' WHERE db_name = \''
  856. . PMA_Util::sqlAddSlashes($db) . '\''
  857. . ' AND table_name = \''
  858. . PMA_Util::sqlAddSlashes($arrvalue['name']) . '\''
  859. . ' AND pdf_page_number = \''
  860. . PMA_Util::sqlAddSlashes($this->chosenPage) . '\'';
  861. }
  862. } else {
  863. $ch_query = 'INSERT INTO '
  864. . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
  865. . '.' . PMA_Util::backquote($cfgRelation['table_coords'])
  866. . ' '
  867. . '(db_name, table_name, pdf_page_number, x, y) '
  868. . 'VALUES (\'' . PMA_Util::sqlAddSlashes($db) . '\', \''
  869. . PMA_Util::sqlAddSlashes($arrvalue['name']) . '\', \''
  870. . PMA_Util::sqlAddSlashes($this->chosenPage) . '\','
  871. . $arrvalue['x'] . ',' . $arrvalue['y'] . ')';
  872. }
  873. //echo $ch_query;
  874. PMA_queryAsControlUser($ch_query, false);
  875. } // end if
  876. } // end for
  877. }
  878. }
  879. ?>