PdfRelationSchema.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * PDF schema handling
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. namespace PhpMyAdmin\Plugins\Schema\Pdf;
  9. use PhpMyAdmin\Pdf as PdfLib;
  10. use PhpMyAdmin\Plugins\Schema\ExportRelationSchema;
  11. use PhpMyAdmin\Relation;
  12. use PhpMyAdmin\Transformations;
  13. use PhpMyAdmin\Util;
  14. /**
  15. * Skip the plugin if TCPDF is not available.
  16. */
  17. if (! class_exists('TCPDF')) {
  18. $GLOBALS['skip_import'] = true;
  19. return;
  20. }
  21. /**
  22. * block attempts to directly run this script
  23. */
  24. if (getcwd() == dirname(__FILE__)) {
  25. die('Attack stopped');
  26. }
  27. /**
  28. * Pdf Relation Schema Class
  29. *
  30. * Purpose of this class is to generate the PDF Document. PDF is widely
  31. * used format for documenting text,fonts,images and 3d vector graphics.
  32. *
  33. * This class inherits ExportRelationSchema class has common functionality added
  34. * to this class
  35. *
  36. * @name Pdf_Relation_Schema
  37. * @package PhpMyAdmin
  38. */
  39. class PdfRelationSchema extends ExportRelationSchema
  40. {
  41. /**
  42. * Defines properties
  43. */
  44. private $_showGrid;
  45. private $_withDoc;
  46. private $_tableOrder;
  47. /**
  48. * @var TableStatsPdf[]
  49. */
  50. private $_tables = array();
  51. private $_ff = PdfLib::PMA_PDF_FONT;
  52. private $_xMax = 0;
  53. private $_yMax = 0;
  54. private $_scale;
  55. private $_xMin = 100000;
  56. private $_yMin = 100000;
  57. private $_topMargin = 10;
  58. private $_bottomMargin = 10;
  59. private $_leftMargin = 10;
  60. private $_rightMargin = 10;
  61. private $_tablewidth;
  62. /**
  63. * @var RelationStatsPdf[]
  64. */
  65. protected $relations = array();
  66. /**
  67. * The "PdfRelationSchema" constructor
  68. *
  69. * @param string $db database name
  70. *
  71. * @see PMA_Schema_PDF
  72. */
  73. public function __construct($db)
  74. {
  75. $this->setShowGrid(isset($_REQUEST['pdf_show_grid']));
  76. $this->setShowColor(isset($_REQUEST['pdf_show_color']));
  77. $this->setShowKeys(isset($_REQUEST['pdf_show_keys']));
  78. $this->setTableDimension(isset($_REQUEST['pdf_show_table_dimension']));
  79. $this->setAllTablesSameWidth(isset($_REQUEST['pdf_all_tables_same_width']));
  80. $this->setWithDataDictionary(isset($_REQUEST['pdf_with_doc']));
  81. $this->setTableOrder($_REQUEST['pdf_table_order']);
  82. $this->setOrientation($_REQUEST['pdf_orientation']);
  83. $this->setPaper($_REQUEST['pdf_paper']);
  84. // Initializes a new document
  85. parent::__construct(
  86. $db,
  87. new Pdf(
  88. $this->orientation, 'mm', $this->paper,
  89. $this->pageNumber, $this->_withDoc, $db
  90. )
  91. );
  92. $this->diagram->SetTitle(
  93. sprintf(
  94. __('Schema of the %s database'),
  95. $this->db
  96. )
  97. );
  98. $this->diagram->setCMargin(0);
  99. $this->diagram->Open();
  100. $this->diagram->SetAutoPageBreak('auto');
  101. $this->diagram->setOffline($this->offline);
  102. $alltables = $this->getTablesFromRequest();
  103. if ($this->getTableOrder() == 'name_asc') {
  104. sort($alltables);
  105. } elseif ($this->getTableOrder() == 'name_desc') {
  106. rsort($alltables);
  107. }
  108. if ($this->_withDoc) {
  109. $this->diagram->SetAutoPageBreak('auto', 15);
  110. $this->diagram->setCMargin(1);
  111. $this->dataDictionaryDoc($alltables);
  112. $this->diagram->SetAutoPageBreak('auto');
  113. $this->diagram->setCMargin(0);
  114. }
  115. $this->diagram->Addpage();
  116. if ($this->_withDoc) {
  117. $this->diagram->SetLink($this->diagram->PMA_links['RT']['-'], -1);
  118. $this->diagram->Bookmark(__('Relational schema'));
  119. $this->diagram->setAlias('{00}', $this->diagram->PageNo());
  120. $this->_topMargin = 28;
  121. $this->_bottomMargin = 28;
  122. }
  123. /* snip */
  124. foreach ($alltables as $table) {
  125. if (! isset($this->_tables[$table])) {
  126. $this->_tables[$table] = new TableStatsPdf(
  127. $this->diagram,
  128. $this->db,
  129. $table,
  130. null,
  131. $this->pageNumber,
  132. $this->_tablewidth,
  133. $this->showKeys,
  134. $this->tableDimension,
  135. $this->offline
  136. );
  137. }
  138. if ($this->sameWide) {
  139. $this->_tables[$table]->width = $this->_tablewidth;
  140. }
  141. $this->_setMinMax($this->_tables[$table]);
  142. }
  143. // Defines the scale factor
  144. $innerWidth = $this->diagram->getPageWidth() - $this->_rightMargin
  145. - $this->_leftMargin;
  146. $innerHeight = $this->diagram->getPageHeight() - $this->_topMargin
  147. - $this->_bottomMargin;
  148. $this->_scale = ceil(
  149. max(
  150. ($this->_xMax - $this->_xMin) / $innerWidth,
  151. ($this->_yMax - $this->_yMin) / $innerHeight
  152. ) * 100
  153. ) / 100;
  154. $this->diagram->setScale(
  155. $this->_scale,
  156. $this->_xMin,
  157. $this->_yMin,
  158. $this->_leftMargin,
  159. $this->_topMargin
  160. );
  161. // Builds and save the PDF document
  162. $this->diagram->setLineWidthScale(0.1);
  163. if ($this->_showGrid) {
  164. $this->diagram->SetFontSize(10);
  165. $this->_strokeGrid();
  166. }
  167. $this->diagram->setFontSizeScale(14);
  168. // previous logic was checking master tables and foreign tables
  169. // but I think that looping on every table of the pdf page as a master
  170. // and finding its foreigns is OK (then we can support innodb)
  171. $seen_a_relation = false;
  172. foreach ($alltables as $one_table) {
  173. $exist_rel = $this->relation->getForeigners($this->db, $one_table, '', 'both');
  174. if (!$exist_rel) {
  175. continue;
  176. }
  177. $seen_a_relation = true;
  178. foreach ($exist_rel as $master_field => $rel) {
  179. // put the foreign table on the schema only if selected
  180. // by the user
  181. // (do not use array_search() because we would have to
  182. // to do a === false and this is not PHP3 compatible)
  183. if ($master_field != 'foreign_keys_data') {
  184. if (in_array($rel['foreign_table'], $alltables)) {
  185. $this->_addRelation(
  186. $one_table,
  187. $master_field,
  188. $rel['foreign_table'],
  189. $rel['foreign_field']
  190. );
  191. }
  192. continue;
  193. }
  194. foreach ($rel as $one_key) {
  195. if (!in_array($one_key['ref_table_name'], $alltables)) {
  196. continue;
  197. }
  198. foreach ($one_key['index_list']
  199. as $index => $one_field
  200. ) {
  201. $this->_addRelation(
  202. $one_table,
  203. $one_field,
  204. $one_key['ref_table_name'],
  205. $one_key['ref_index_list'][$index]
  206. );
  207. }
  208. }
  209. } // end while
  210. } // end while
  211. if ($seen_a_relation) {
  212. $this->_drawRelations();
  213. }
  214. $this->_drawTables();
  215. }
  216. /**
  217. * Set Show Grid
  218. *
  219. * @param boolean $value show grid of the document or not
  220. *
  221. * @return void
  222. */
  223. public function setShowGrid($value)
  224. {
  225. $this->_showGrid = $value;
  226. }
  227. /**
  228. * Returns whether to show grid
  229. *
  230. * @return boolean whether to show grid
  231. */
  232. public function isShowGrid()
  233. {
  234. return $this->_showGrid;
  235. }
  236. /**
  237. * Set Data Dictionary
  238. *
  239. * @param boolean $value show selected database data dictionary or not
  240. *
  241. * @return void
  242. */
  243. public function setWithDataDictionary($value)
  244. {
  245. $this->_withDoc = $value;
  246. }
  247. /**
  248. * Return whether to show selected database data dictionary or not
  249. *
  250. * @return boolean whether to show selected database data dictionary or not
  251. */
  252. public function isWithDataDictionary()
  253. {
  254. return $this->_withDoc;
  255. }
  256. /**
  257. * Sets the order of the table in data dictionary
  258. *
  259. * @param string $value table order
  260. *
  261. * @return void
  262. */
  263. public function setTableOrder($value)
  264. {
  265. $this->_tableOrder = $value;
  266. }
  267. /**
  268. * Returns the order of the table in data dictionary
  269. *
  270. * @return string table order
  271. */
  272. public function getTableOrder()
  273. {
  274. return $this->_tableOrder;
  275. }
  276. /**
  277. * Output Pdf Document for download
  278. *
  279. * @return void
  280. */
  281. public function showOutput()
  282. {
  283. $this->diagram->download($this->getFileName('.pdf'));
  284. }
  285. /**
  286. * Sets X and Y minimum and maximum for a table cell
  287. *
  288. * @param TableStatsPdf $table The table name of which sets XY co-ordinates
  289. *
  290. * @return void
  291. */
  292. private function _setMinMax($table)
  293. {
  294. $this->_xMax = max($this->_xMax, $table->x + $table->width);
  295. $this->_yMax = max($this->_yMax, $table->y + $table->height);
  296. $this->_xMin = min($this->_xMin, $table->x);
  297. $this->_yMin = min($this->_yMin, $table->y);
  298. }
  299. /**
  300. * Defines relation objects
  301. *
  302. * @param string $masterTable The master table name
  303. * @param string $masterField The relation field in the master table
  304. * @param string $foreignTable The foreign table name
  305. * @param string $foreignField The relation field in the foreign table
  306. *
  307. * @return void
  308. *
  309. * @see _setMinMax
  310. */
  311. private function _addRelation($masterTable, $masterField, $foreignTable,
  312. $foreignField
  313. ) {
  314. if (! isset($this->_tables[$masterTable])) {
  315. $this->_tables[$masterTable] = new TableStatsPdf(
  316. $this->diagram,
  317. $this->db,
  318. $masterTable,
  319. null,
  320. $this->pageNumber,
  321. $this->_tablewidth,
  322. $this->showKeys,
  323. $this->tableDimension
  324. );
  325. $this->_setMinMax($this->_tables[$masterTable]);
  326. }
  327. if (! isset($this->_tables[$foreignTable])) {
  328. $this->_tables[$foreignTable] = new TableStatsPdf(
  329. $this->diagram,
  330. $this->db,
  331. $foreignTable,
  332. null,
  333. $this->pageNumber,
  334. $this->_tablewidth,
  335. $this->showKeys,
  336. $this->tableDimension
  337. );
  338. $this->_setMinMax($this->_tables[$foreignTable]);
  339. }
  340. $this->relations[] = new RelationStatsPdf(
  341. $this->diagram,
  342. $this->_tables[$masterTable],
  343. $masterField,
  344. $this->_tables[$foreignTable],
  345. $foreignField
  346. );
  347. }
  348. /**
  349. * Draws the grid
  350. *
  351. * @return void
  352. *
  353. * @see PMA_Schema_PDF
  354. */
  355. private function _strokeGrid()
  356. {
  357. $gridSize = 10;
  358. $labelHeight = 4;
  359. $labelWidth = 5;
  360. if ($this->_withDoc) {
  361. $topSpace = 6;
  362. $bottomSpace = 15;
  363. } else {
  364. $topSpace = 0;
  365. $bottomSpace = 0;
  366. }
  367. $this->diagram->SetMargins(0, 0);
  368. $this->diagram->SetDrawColor(200, 200, 200);
  369. // Draws horizontal lines
  370. $innerHeight = $this->diagram->getPageHeight() - $topSpace - $bottomSpace;
  371. for ($l = 0,
  372. $size = intval($innerHeight / $gridSize);
  373. $l <= $size;
  374. $l++
  375. ) {
  376. $this->diagram->line(
  377. 0, $l * $gridSize + $topSpace,
  378. $this->diagram->getPageWidth(), $l * $gridSize + $topSpace
  379. );
  380. // Avoid duplicates
  381. if ($l > 0
  382. && $l <= intval(($innerHeight - $labelHeight) / $gridSize)
  383. ) {
  384. $this->diagram->SetXY(0, $l * $gridSize + $topSpace);
  385. $label = (string) sprintf(
  386. '%.0f',
  387. ($l * $gridSize + $topSpace - $this->_topMargin)
  388. * $this->_scale + $this->_yMin
  389. );
  390. $this->diagram->Cell($labelWidth, $labelHeight, ' ' . $label);
  391. } // end if
  392. } // end for
  393. // Draws vertical lines
  394. for (
  395. $j = 0, $size = intval($this->diagram->getPageWidth() / $gridSize);
  396. $j <= $size;
  397. $j++
  398. ) {
  399. $this->diagram->line(
  400. $j * $gridSize,
  401. $topSpace,
  402. $j * $gridSize,
  403. $this->diagram->getPageHeight() - $bottomSpace
  404. );
  405. $this->diagram->SetXY($j * $gridSize, $topSpace);
  406. $label = (string) sprintf(
  407. '%.0f',
  408. ($j * $gridSize - $this->_leftMargin) * $this->_scale + $this->_xMin
  409. );
  410. $this->diagram->Cell($labelWidth, $labelHeight, $label);
  411. }
  412. }
  413. /**
  414. * Draws relation arrows
  415. *
  416. * @return void
  417. *
  418. * @see Relation_Stats_Pdf::relationdraw()
  419. */
  420. private function _drawRelations()
  421. {
  422. $i = 0;
  423. foreach ($this->relations as $relation) {
  424. $relation->relationDraw($this->showColor, $i);
  425. $i++;
  426. }
  427. }
  428. /**
  429. * Draws tables
  430. *
  431. * @return void
  432. *
  433. * @see Table_Stats_Pdf::tableDraw()
  434. */
  435. private function _drawTables()
  436. {
  437. foreach ($this->_tables as $table) {
  438. $table->tableDraw(null, $this->_withDoc, $this->showColor);
  439. }
  440. }
  441. /**
  442. * Generates data dictionary pages.
  443. *
  444. * @param array $alltables Tables to document.
  445. *
  446. * @return void
  447. */
  448. public function dataDictionaryDoc(array $alltables)
  449. {
  450. // TOC
  451. $this->diagram->addpage($this->orientation);
  452. $this->diagram->Cell(0, 9, __('Table of contents'), 1, 0, 'C');
  453. $this->diagram->Ln(15);
  454. $i = 1;
  455. foreach ($alltables as $table) {
  456. $this->diagram->PMA_links['doc'][$table]['-']
  457. = $this->diagram->AddLink();
  458. $this->diagram->SetX(10);
  459. // $this->diagram->Ln(1);
  460. $this->diagram->Cell(
  461. 0, 6, __('Page number:') . ' {' . sprintf("%02d", $i) . '}', 0, 0,
  462. 'R', 0, $this->diagram->PMA_links['doc'][$table]['-']
  463. );
  464. $this->diagram->SetX(10);
  465. $this->diagram->Cell(
  466. 0, 6, $i . ' ' . $table, 0, 1,
  467. 'L', 0, $this->diagram->PMA_links['doc'][$table]['-']
  468. );
  469. // $this->diagram->Ln(1);
  470. $fields = $GLOBALS['dbi']->getColumns($this->db, $table);
  471. foreach ($fields as $row) {
  472. $this->diagram->SetX(20);
  473. $field_name = $row['Field'];
  474. $this->diagram->PMA_links['doc'][$table][$field_name]
  475. = $this->diagram->AddLink();
  476. //$this->diagram->Cell(
  477. // 0, 6, $field_name, 0, 1,
  478. // 'L', 0, $this->diagram->PMA_links['doc'][$table][$field_name]
  479. //);
  480. }
  481. $i++;
  482. }
  483. $this->diagram->PMA_links['RT']['-'] = $this->diagram->AddLink();
  484. $this->diagram->SetX(10);
  485. $this->diagram->Cell(
  486. 0, 6, __('Page number:') . ' {00}', 0, 0,
  487. 'R', 0, $this->diagram->PMA_links['RT']['-']
  488. );
  489. $this->diagram->SetX(10);
  490. $this->diagram->Cell(
  491. 0, 6, $i . ' ' . __('Relational schema'), 0, 1,
  492. 'L', 0, $this->diagram->PMA_links['RT']['-']
  493. );
  494. $z = 0;
  495. foreach ($alltables as $table) {
  496. $z++;
  497. $this->diagram->SetAutoPageBreak(true, 15);
  498. $this->diagram->addpage($this->orientation);
  499. $this->diagram->Bookmark($table);
  500. $this->diagram->setAlias(
  501. '{' . sprintf("%02d", $z) . '}', $this->diagram->PageNo()
  502. );
  503. $this->diagram->PMA_links['RT'][$table]['-']
  504. = $this->diagram->AddLink();
  505. $this->diagram->SetLink(
  506. $this->diagram->PMA_links['doc'][$table]['-'], -1
  507. );
  508. $this->diagram->SetFont($this->_ff, 'B', 18);
  509. $this->diagram->Cell(
  510. 0, 8, $z . ' ' . $table, 1, 1,
  511. 'C', 0, $this->diagram->PMA_links['RT'][$table]['-']
  512. );
  513. $this->diagram->SetFont($this->_ff, '', 8);
  514. $this->diagram->ln();
  515. $cfgRelation = $this->relation->getRelationsParam();
  516. $comments = $this->relation->getComments($this->db, $table);
  517. if ($cfgRelation['mimework']) {
  518. $mime_map = Transformations::getMIME($this->db, $table, true);
  519. }
  520. /**
  521. * Gets table information
  522. */
  523. $showtable = $GLOBALS['dbi']->getTable($this->db, $table)
  524. ->getStatusInfo();
  525. $show_comment = isset($showtable['Comment'])
  526. ? $showtable['Comment']
  527. : '';
  528. $create_time = isset($showtable['Create_time'])
  529. ? Util::localisedDate(
  530. strtotime($showtable['Create_time'])
  531. )
  532. : '';
  533. $update_time = isset($showtable['Update_time'])
  534. ? Util::localisedDate(
  535. strtotime($showtable['Update_time'])
  536. )
  537. : '';
  538. $check_time = isset($showtable['Check_time'])
  539. ? Util::localisedDate(
  540. strtotime($showtable['Check_time'])
  541. )
  542. : '';
  543. /**
  544. * Gets fields properties
  545. */
  546. $columns = $GLOBALS['dbi']->getColumns($this->db, $table);
  547. // Find which tables are related with the current one and write it in
  548. // an array
  549. $res_rel = $this->relation->getForeigners($this->db, $table);
  550. /**
  551. * Displays the comments of the table if MySQL >= 3.23
  552. */
  553. $break = false;
  554. if (! empty($show_comment)) {
  555. $this->diagram->Cell(
  556. 0, 3, __('Table comments:') . ' ' . $show_comment, 0, 1
  557. );
  558. $break = true;
  559. }
  560. if (! empty($create_time)) {
  561. $this->diagram->Cell(
  562. 0, 3, __('Creation:') . ' ' . $create_time, 0, 1
  563. );
  564. $break = true;
  565. }
  566. if (! empty($update_time)) {
  567. $this->diagram->Cell(
  568. 0, 3, __('Last update:') . ' ' . $update_time, 0, 1
  569. );
  570. $break = true;
  571. }
  572. if (! empty($check_time)) {
  573. $this->diagram->Cell(
  574. 0, 3, __('Last check:') . ' ' . $check_time, 0, 1
  575. );
  576. $break = true;
  577. }
  578. if ($break == true) {
  579. $this->diagram->Cell(0, 3, '', 0, 1);
  580. $this->diagram->Ln();
  581. }
  582. $this->diagram->SetFont($this->_ff, 'B');
  583. if (isset($this->orientation) && $this->orientation == 'L') {
  584. $this->diagram->Cell(25, 8, __('Column'), 1, 0, 'C');
  585. $this->diagram->Cell(20, 8, __('Type'), 1, 0, 'C');
  586. $this->diagram->Cell(20, 8, __('Attributes'), 1, 0, 'C');
  587. $this->diagram->Cell(10, 8, __('Null'), 1, 0, 'C');
  588. $this->diagram->Cell(20, 8, __('Default'), 1, 0, 'C');
  589. $this->diagram->Cell(25, 8, __('Extra'), 1, 0, 'C');
  590. $this->diagram->Cell(45, 8, __('Links to'), 1, 0, 'C');
  591. if ($this->paper == 'A4') {
  592. $comments_width = 67;
  593. } else {
  594. // this is really intended for 'letter'
  595. /**
  596. * @todo find optimal width for all formats
  597. */
  598. $comments_width = 50;
  599. }
  600. $this->diagram->Cell($comments_width, 8, __('Comments'), 1, 0, 'C');
  601. $this->diagram->Cell(45, 8, 'MIME', 1, 1, 'C');
  602. $this->diagram->setWidths(
  603. array(25, 20, 20, 10, 20, 25, 45, $comments_width, 45)
  604. );
  605. } else {
  606. $this->diagram->Cell(20, 8, __('Column'), 1, 0, 'C');
  607. $this->diagram->Cell(20, 8, __('Type'), 1, 0, 'C');
  608. $this->diagram->Cell(20, 8, __('Attributes'), 1, 0, 'C');
  609. $this->diagram->Cell(10, 8, __('Null'), 1, 0, 'C');
  610. $this->diagram->Cell(15, 8, __('Default'), 1, 0, 'C');
  611. $this->diagram->Cell(15, 8, __('Extra'), 1, 0, 'C');
  612. $this->diagram->Cell(30, 8, __('Links to'), 1, 0, 'C');
  613. $this->diagram->Cell(30, 8, __('Comments'), 1, 0, 'C');
  614. $this->diagram->Cell(30, 8, 'MIME', 1, 1, 'C');
  615. $this->diagram->setWidths(array(20, 20, 20, 10, 15, 15, 30, 30, 30));
  616. }
  617. $this->diagram->SetFont($this->_ff, '');
  618. foreach ($columns as $row) {
  619. $extracted_columnspec
  620. = Util::extractColumnSpec($row['Type']);
  621. $type = $extracted_columnspec['print_type'];
  622. $attribute = $extracted_columnspec['attribute'];
  623. if (! isset($row['Default'])) {
  624. if ($row['Null'] != '' && $row['Null'] != 'NO') {
  625. $row['Default'] = 'NULL';
  626. }
  627. }
  628. $field_name = $row['Field'];
  629. // $this->diagram->Ln();
  630. $this->diagram->PMA_links['RT'][$table][$field_name]
  631. = $this->diagram->AddLink();
  632. $this->diagram->Bookmark($field_name, 1, -1);
  633. $this->diagram->SetLink(
  634. $this->diagram->PMA_links['doc'][$table][$field_name], -1
  635. );
  636. $foreigner = $this->relation->searchColumnInForeigners($res_rel, $field_name);
  637. $linksTo = '';
  638. if ($foreigner) {
  639. $linksTo = '-> ';
  640. if ($foreigner['foreign_db'] != $this->db) {
  641. $linksTo .= $foreigner['foreign_db'] . '.';
  642. }
  643. $linksTo .= $foreigner['foreign_table']
  644. . '.' . $foreigner['foreign_field'];
  645. if (isset($foreigner['on_update'])) { // not set for internal
  646. $linksTo .= "\n" . 'ON UPDATE ' . $foreigner['on_update'];
  647. $linksTo .= "\n" . 'ON DELETE ' . $foreigner['on_delete'];
  648. }
  649. }
  650. $this->diagram_row = array(
  651. $field_name,
  652. $type,
  653. $attribute,
  654. (($row['Null'] == '' || $row['Null'] == 'NO')
  655. ? __('No')
  656. : __('Yes')),
  657. (isset($row['Default']) ? $row['Default'] : ''),
  658. $row['Extra'],
  659. $linksTo,
  660. (isset($comments[$field_name])
  661. ? $comments[$field_name]
  662. : ''),
  663. (isset($mime_map) && isset($mime_map[$field_name])
  664. ? str_replace('_', '/', $mime_map[$field_name]['mimetype'])
  665. : '')
  666. );
  667. $links = array();
  668. $links[0] = $this->diagram->PMA_links['RT'][$table][$field_name];
  669. if ($foreigner
  670. && isset($this->diagram->PMA_links['doc'][$foreigner['foreign_table']][$foreigner['foreign_field']])
  671. ) {
  672. $links[6] = $this->diagram->PMA_links['doc']
  673. [$foreigner['foreign_table']][$foreigner['foreign_field']];
  674. } else {
  675. unset($links[6]);
  676. }
  677. $this->diagram->row($this->diagram_row, $links);
  678. } // end foreach
  679. $this->diagram->SetFont($this->_ff, '', 14);
  680. } //end each
  681. }
  682. }