PageRenderTime 62ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/pma/pdf_schema.php

https://bitbucket.org/StasPiv/playzone
PHP | 1397 lines | 913 code | 74 blank | 410 comment | 164 complexity | b87e0c332f4a45690f0f1b0e477bdd17 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, GPL-2.0, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Contributed by Maxime Delorme and merged by lem9
  5. *
  6. * @version $Id: pdf_schema.php 12120 2008-12-10 09:22:29Z cybot_tm $
  7. * @package phpMyAdmin
  8. */
  9. /**
  10. * Gets some core scripts
  11. */
  12. require_once './libraries/common.inc.php';
  13. /**
  14. * Settings for relation stuff
  15. */
  16. require_once './libraries/relation.lib.php';
  17. require_once './libraries/transformations.lib.php';
  18. require_once './libraries/Index.class.php';
  19. $cfgRelation = PMA_getRelationsParam();
  20. /**
  21. * Now in ./libraries/relation.lib.php we check for all tables
  22. * that we need, but if we don't find them we are quiet about it
  23. * so people can work without.
  24. * This page is absolutely useless if you didn't set up your tables
  25. * correctly, so it is a good place to see which tables we can and
  26. * complain ;-)
  27. */
  28. if (!$cfgRelation['pdfwork']) {
  29. echo '<font color="red">' . $strError . '</font><br />' . "\n";
  30. $url_to_goto = '<a href="' . $cfg['PmaAbsoluteUri'] . 'chk_rel.php?' . $url_query . '">';
  31. echo sprintf($strRelationNotWorking, $url_to_goto, '</a>') . "\n";
  32. }
  33. /**
  34. * Font used in PDF.
  35. *
  36. * @todo Make this configuratble (at least Sans/Serif).
  37. */
  38. define('PMA_PDF_FONT', 'DejaVuSans');
  39. require_once './libraries/tcpdf/tcpdf.php';
  40. /**
  41. * Extends the "FPDF" class and prepares the work
  42. *
  43. * @access public
  44. * @see FPDF
  45. * @package phpMyAdmin
  46. */
  47. class PMA_PDF extends TCPDF {
  48. /**
  49. * Defines private properties
  50. */
  51. var $x_min;
  52. var $y_min;
  53. var $l_marg = 10;
  54. var $t_marg = 10;
  55. var $scale;
  56. var $PMA_links;
  57. var $Outlines = array();
  58. var $def_outlines;
  59. var $Alias = array();
  60. var $widths;
  61. public function getFh()
  62. {
  63. return $this->fh;
  64. }
  65. public function getFw()
  66. {
  67. return $this->fw;
  68. }
  69. public function setCMargin($c_margin)
  70. {
  71. $this->cMargin = $c_margin;
  72. }
  73. function SetAlias($name, $value)
  74. {
  75. $this->Alias[$name] = $value ;
  76. }
  77. function _putpages()
  78. {
  79. if (count($this->Alias) > 0) {
  80. $nb = $this->page;
  81. foreach ($this->Alias AS $alias => $value) {
  82. for ($n = 1;$n <= $nb;$n++)
  83. $this->pages[$n]=str_replace($alias, $value, $this->pages[$n]);
  84. }
  85. }
  86. parent::_putpages();
  87. }
  88. /**
  89. * Sets the scaling factor, defines minimum coordinates and margins
  90. *
  91. * @param double $ The scaling factor
  92. * @param double $ The minimum X coordinate
  93. * @param double $ The minimum Y coordinate
  94. * @param double $ The left margin
  95. * @param double $ The top margin
  96. * @access public
  97. */
  98. function PMA_PDF_setScale($scale = 1, $x_min = 0, $y_min = 0, $l_marg = -1, $t_marg = -1)
  99. {
  100. $this->scale = $scale;
  101. $this->x_min = $x_min;
  102. $this->y_min = $y_min;
  103. if ($this->l_marg != -1) {
  104. $this->l_marg = $l_marg;
  105. }
  106. if ($this->t_marg != -1) {
  107. $this->t_marg = $t_marg;
  108. }
  109. } // end of the "PMA_PDF_setScale" function
  110. /**
  111. * Outputs a scaled cell
  112. *
  113. * @param double $ The cell width
  114. * @param double $ The cell height
  115. * @param string $ The text to output
  116. * @param mixed $ Whether to add borders or not
  117. * @param integer $ Where to put the cursor once the output is done
  118. * @param string $ Align mode
  119. * @param integer $ Whether to fill the cell with a color or not
  120. * @access public
  121. * @see FPDF::Cell()
  122. */
  123. function PMA_PDF_cellScale($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = 0, $link = '')
  124. {
  125. $h = $h / $this->scale;
  126. $w = $w / $this->scale;
  127. $this->Cell($w, $h, $txt, $border, $ln, $align, $fill, $link);
  128. } // end of the "PMA_PDF_cellScale" function
  129. /**
  130. * Draws a scaled line
  131. *
  132. * @param double $ The horizontal position of the starting point
  133. * @param double $ The vertical position of the starting point
  134. * @param double $ The horizontal position of the ending point
  135. * @param double $ The vertical position of the ending point
  136. * @access public
  137. * @see FPDF::Line()
  138. */
  139. function PMA_PDF_lineScale($x1, $y1, $x2, $y2)
  140. {
  141. $x1 = ($x1 - $this->x_min) / $this->scale + $this->l_marg;
  142. $y1 = ($y1 - $this->y_min) / $this->scale + $this->t_marg;
  143. $x2 = ($x2 - $this->x_min) / $this->scale + $this->l_marg;
  144. $y2 = ($y2 - $this->y_min) / $this->scale + $this->t_marg;
  145. $this->Line($x1, $y1, $x2, $y2);
  146. } // end of the "PMA_PDF_lineScale" function
  147. /**
  148. * Sets x and y scaled positions
  149. *
  150. * @param double $ The x position
  151. * @param double $ The y position
  152. * @access public
  153. * @see FPDF::SetXY()
  154. */
  155. function PMA_PDF_setXyScale($x, $y)
  156. {
  157. $x = ($x - $this->x_min) / $this->scale + $this->l_marg;
  158. $y = ($y - $this->y_min) / $this->scale + $this->t_marg;
  159. $this->SetXY($x, $y);
  160. } // end of the "PMA_PDF_setXyScale" function
  161. /**
  162. * Sets the X scaled positions
  163. *
  164. * @param double $ The x position
  165. * @access public
  166. * @see FPDF::SetX()
  167. */
  168. function PMA_PDF_setXScale($x)
  169. {
  170. $x = ($x - $this->x_min) / $this->scale + $this->l_marg;
  171. $this->SetX($x);
  172. } // end of the "PMA_PDF_setXScale" function
  173. /**
  174. * Sets the scaled font size
  175. *
  176. * @param double $ The font size (in points)
  177. * @access public
  178. * @see FPDF::SetFontSize()
  179. */
  180. function PMA_PDF_setFontSizeScale($size)
  181. {
  182. // Set font size in points
  183. $size = $size / $this->scale;
  184. $this->SetFontSize($size);
  185. } // end of the "PMA_PDF_setFontSizeScale" function
  186. /**
  187. * Sets the scaled line width
  188. *
  189. * @param double $ The line width
  190. * @access public
  191. * @see FPDF::SetLineWidth()
  192. */
  193. function PMA_PDF_setLineWidthScale($width)
  194. {
  195. $width = $width / $this->scale;
  196. $this->SetLineWidth($width);
  197. } // end of the "PMA_PDF_setLineWidthScale" function
  198. /**
  199. * Displays an error message
  200. *
  201. * @param string $ the error mesage
  202. * @global array the PMA configuration array
  203. * @global integer the current server id
  204. * @global string the current language
  205. * @global string the charset to convert to
  206. * @global string the current database name
  207. * @global string the current charset
  208. * @global string the current text direction
  209. * @global string a localized string
  210. * @global string an other localized string
  211. * @access public
  212. */
  213. function PMA_PDF_die($error_message = '')
  214. {
  215. global $cfg;
  216. global $server, $lang, $convcharset, $db;
  217. global $charset, $text_dir, $strRunning, $strDatabase;
  218. require_once './libraries/header.inc.php';
  219. echo '<p><strong>PDF - ' . $GLOBALS['strError'] . '</strong></p>' . "\n";
  220. if (!empty($error_message)) {
  221. $error_message = htmlspecialchars($error_message);
  222. }
  223. echo '<p>' . "\n";
  224. echo ' ' . $error_message . "\n";
  225. echo '</p>' . "\n";
  226. echo '<a href="db_structure.php?' . PMA_generate_common_url($db)
  227. . '">' . $GLOBALS['strBack'] . '</a>';
  228. echo "\n";
  229. require_once './libraries/footer.inc.php';
  230. } // end of the "PMA_PDF_die()" function
  231. /**
  232. * Aliases the "Error()" function from the FPDF class to the
  233. * "PMA_PDF_die()" one
  234. *
  235. * @param string $ the error mesage
  236. * @access public
  237. * @see PMA_PDF_die
  238. */
  239. function Error($error_message = '')
  240. {
  241. $this->PMA_PDF_die($error_message);
  242. } // end of the "Error()" method
  243. function Header()
  244. {
  245. // $datefmt
  246. // We only show this if we find something in the new pdf_pages table
  247. // This function must be named "Header" to work with the FPDF library
  248. global $cfgRelation, $db, $pdf_page_number, $with_doc;
  249. if ($with_doc) {
  250. $test_query = 'SELECT * FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['pdf_pages'])
  251. . ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
  252. . ' AND page_nr = \'' . $pdf_page_number . '\'';
  253. $test_rs = PMA_query_as_cu($test_query);
  254. $pages = @PMA_DBI_fetch_assoc($test_rs);
  255. $this->SetFont('', 'B', 14);
  256. $this->Cell(0, 6, ucfirst($pages['page_descr']), 'B', 1, 'C');
  257. $this->SetFont('', '');
  258. $this->Ln();
  259. }
  260. }
  261. function Footer()
  262. {
  263. // This function must be named "Footer" to work with the FPDF library
  264. global $with_doc;
  265. if ($with_doc) {
  266. $this->SetY(-15);
  267. $this->SetFont('', '', 14);
  268. $this->Cell(0, 6, $GLOBALS['strPageNumber'] . ' ' . $this->PageNo() . '/{nb}', 'T', 0, 'C');
  269. $this->Cell(0, 6, PMA_localisedDate(), 0, 1, 'R');
  270. $this->SetY(20);
  271. }
  272. }
  273. function Bookmark($txt, $level = 0, $y = 0)
  274. {
  275. // Add a bookmark
  276. $this->Outlines[0][] = $level;
  277. $this->Outlines[1][] = $txt;
  278. $this->Outlines[2][] = $this->page;
  279. if ($y == -1) {
  280. $y = $this->GetY();
  281. }
  282. $this->Outlines[3][] = round($this->hPt - $y * $this->k, 2);
  283. }
  284. function _putbookmarks()
  285. {
  286. if (count($this->Outlines) > 0) {
  287. // Save object number
  288. $memo_n = $this->n;
  289. // Take the number of sub elements for an outline
  290. $nb_outlines = sizeof($this->Outlines[0]);
  291. $first_level = array();
  292. $parent = array();
  293. $parent[0] = 1;
  294. for ($i = 0; $i < $nb_outlines; $i++) {
  295. $level = $this->Outlines[0][$i];
  296. $kids = 0;
  297. $last = -1;
  298. $prev = -1;
  299. $next = -1;
  300. if ($i > 0) {
  301. $cursor = $i-1;
  302. // Take the previous outline in the same level
  303. while ($this->Outlines[0][$cursor] > $level && $cursor > 0)
  304. $cursor--;
  305. if ($this->Outlines[0][$cursor] == $level) {
  306. $prev = $cursor;
  307. }
  308. }
  309. if ($i < $nb_outlines-1) {
  310. $cursor = $i + 1;
  311. while (isset($this->Outlines[0][$cursor]) && $this->Outlines[0][$cursor] > $level) {
  312. // Take the immediate kid in level + 1
  313. if ($this->Outlines[0][$cursor] == $level + 1) {
  314. $kids++;
  315. $last = $cursor;
  316. }
  317. $cursor++;
  318. }
  319. $cursor = $i + 1;
  320. // Take the next outline in the same level
  321. while ($this->Outlines[0][$cursor] > $level && ($cursor + 1 < sizeof($this->Outlines[0])))
  322. $cursor++;
  323. if ($this->Outlines[0][$cursor] == $level) {
  324. $next = $cursor;
  325. }
  326. }
  327. $this->_newobj();
  328. $parent[$level + 1] = $this->n;
  329. if ($level == 0) {
  330. $first_level[] = $this->n;
  331. }
  332. $this->_out('<<');
  333. $this->_out('/Title (' . $this->Outlines[1][$i] . ')');
  334. $this->_out('/Parent ' . $parent[$level] . ' 0 R');
  335. if ($prev != -1) {
  336. $this->_out('/Prev ' . ($memo_n + $prev + 1) . ' 0 R');
  337. }
  338. if ($next != -1) {
  339. $this->_out('/Next ' . ($this->n + $next - $i) . ' 0 R');
  340. }
  341. $this->_out('/Dest [' . (1 + (2 * $this->Outlines[2][$i])) . ' 0 R /XYZ null ' . $this->Outlines[3][$i] . ' null]');
  342. if ($kids > 0) {
  343. $this->_out('/First ' . ($this->n + 1) . ' 0 R');
  344. $this->_out('/Last ' . ($this->n + $last - $i) . ' 0 R');
  345. $this->_out('/Count -' . $kids);
  346. }
  347. $this->_out('>>');
  348. $this->_out('endobj');
  349. }
  350. // First page of outlines
  351. $this->_newobj();
  352. $this->def_outlines = $this->n;
  353. $this->_out('<<');
  354. $this->_out('/Type');
  355. $this->_out('/Outlines');
  356. $this->_out('/First ' . $first_level[0] . ' 0 R');
  357. $this->_out('/Last ' . $first_level[sizeof($first_level)-1] . ' 0 R');
  358. $this->_out('/Count ' . sizeof($first_level));
  359. $this->_out('>>');
  360. $this->_out('endobj');
  361. }
  362. }
  363. function _putresources()
  364. {
  365. parent::_putresources();
  366. $this->_putbookmarks();
  367. }
  368. function _putcatalog()
  369. {
  370. parent::_putcatalog();
  371. if (count($this->Outlines) > 0) {
  372. $this->_out('/Outlines ' . $this->def_outlines . ' 0 R');
  373. $this->_out('/PageMode /UseOutlines');
  374. }
  375. }
  376. function SetWidths($w)
  377. {
  378. // column widths
  379. $this->widths = $w;
  380. }
  381. function Row($data, $links)
  382. {
  383. // line height
  384. $nb = 0;
  385. $data_cnt = count($data);
  386. for ($i = 0;$i < $data_cnt;$i++)
  387. $nb = max($nb, $this->NbLines($this->widths[$i], $data[$i]));
  388. $il = $this->FontSize;
  389. $h = ($il + 1) * $nb;
  390. // page break if necessary
  391. $this->CheckPageBreak($h);
  392. // draw the cells
  393. $data_cnt = count($data);
  394. for ($i = 0;$i < $data_cnt;$i++) {
  395. $w = $this->widths[$i];
  396. // save current position
  397. $x = $this->GetX();
  398. $y = $this->GetY();
  399. // draw the border
  400. $this->Rect($x, $y, $w, $h);
  401. if (isset($links[$i])) {
  402. $this->Link($x, $y, $w, $h, $links[$i]);
  403. }
  404. // print text
  405. $this->MultiCell($w, $il + 1, $data[$i], 0, 'L');
  406. // go to right side
  407. $this->SetXY($x + $w, $y);
  408. }
  409. // go to line
  410. $this->Ln($h);
  411. }
  412. function CheckPageBreak($h)
  413. {
  414. // if height h overflows, manual page break
  415. if ($this->GetY() + $h > $this->PageBreakTrigger) {
  416. $this->AddPage($this->CurOrientation);
  417. }
  418. }
  419. function NbLines($w, $txt)
  420. {
  421. // compute number of lines used by a multicell of width w
  422. $cw = &$this->CurrentFont['cw'];
  423. if ($w == 0) {
  424. $w = $this->w - $this->rMargin - $this->x;
  425. }
  426. $wmax = ($w-2 * $this->cMargin) * 1000 / $this->FontSize;
  427. $s = str_replace("\r", '', $txt);
  428. $nb = strlen($s);
  429. if ($nb > 0 and $s[$nb-1] == "\n") {
  430. $nb--;
  431. }
  432. $sep = -1;
  433. $i = 0;
  434. $j = 0;
  435. $l = 0;
  436. $nl = 1;
  437. while ($i < $nb) {
  438. $c = $s[$i];
  439. if ($c == "\n") {
  440. $i++;
  441. $sep = -1;
  442. $j = $i;
  443. $l = 0;
  444. $nl++;
  445. continue;
  446. }
  447. if ($c == ' ') {
  448. $sep = $i;
  449. }
  450. $l += isset($cw[ord($c)])?$cw[ord($c)]:0 ;
  451. if ($l > $wmax) {
  452. if ($sep == -1) {
  453. if ($i == $j) {
  454. $i++;
  455. }
  456. } else {
  457. $i = $sep + 1;
  458. }
  459. $sep = -1;
  460. $j = $i;
  461. $l = 0;
  462. $nl++;
  463. } else {
  464. $i++;
  465. }
  466. }
  467. return $nl;
  468. }
  469. } // end of the "PMA_PDF" class
  470. /**
  471. * Draws tables schema
  472. *
  473. * @access private
  474. * @see PMA_RT
  475. * @package phpMyAdmin
  476. */
  477. class PMA_RT_Table {
  478. /**
  479. * Defines private properties
  480. */
  481. var $nb_fiels;
  482. var $table_name;
  483. var $width = 0;
  484. var $height;
  485. var $fields = array();
  486. var $height_cell = 6;
  487. var $x, $y;
  488. var $primary = array();
  489. /**
  490. * Sets the width of the table
  491. *
  492. * @param integer $ The font size
  493. * @global object The current PDF document
  494. * @access private
  495. * @see PMA_PDF
  496. */
  497. function PMA_RT_Table_setWidth($ff)
  498. {
  499. // this looks buggy to me... does it really work if
  500. // there are fields that require wider cells than the name of the table?
  501. global $pdf;
  502. foreach ($this->fields AS $field) {
  503. $this->width = max($this->width, $pdf->GetStringWidth($field));
  504. }
  505. $this->width += $pdf->GetStringWidth(' ');
  506. $pdf->SetFont($ff, 'B');
  507. $this->width = max($this->width, $pdf->GetStringWidth(' ' . $this->table_name));
  508. $pdf->SetFont($ff, '');
  509. } // end of the "PMA_RT_Table_setWidth()" method
  510. /**
  511. * Sets the height of the table
  512. *
  513. * @access private
  514. */
  515. function PMA_RT_Table_setHeight()
  516. {
  517. $this->height = (count($this->fields) + 1) * $this->height_cell;
  518. } // end of the "PMA_RT_Table_setHeight()" method
  519. /**
  520. * Do draw the table
  521. *
  522. * @param boolean $ Whether to display table position or not
  523. * @param integer $ The font size
  524. * @param boolean $ Whether to display color
  525. * @param integer $ The max. with among tables
  526. * @global object The current PDF document
  527. * @access private
  528. * @see PMA_PDF
  529. */
  530. function PMA_RT_Table_draw($show_info, $ff, $setcolor = 0)
  531. {
  532. global $pdf, $with_doc;
  533. $pdf->PMA_PDF_setXyScale($this->x, $this->y);
  534. $pdf->SetFont($ff, 'B');
  535. if ($setcolor) {
  536. $pdf->SetTextColor(200);
  537. $pdf->SetFillColor(0, 0, 128);
  538. }
  539. if ($with_doc) {
  540. $pdf->SetLink($pdf->PMA_links['RT'][$this->table_name]['-'], -1);
  541. } else {
  542. $pdf->PMA_links['doc'][$this->table_name]['-'] = '';
  543. }
  544. if ($show_info) {
  545. $pdf->PMA_PDF_cellScale($this->width, $this->height_cell, sprintf('%.0f', $this->width) . 'x' . sprintf('%.0f', $this->height) . ' ' . $this->table_name, 1, 1, 'C', $setcolor, $pdf->PMA_links['doc'][$this->table_name]['-']);
  546. } else {
  547. $pdf->PMA_PDF_cellScale($this->width, $this->height_cell, $this->table_name, 1, 1, 'C', $setcolor, $pdf->PMA_links['doc'][$this->table_name]['-']);
  548. }
  549. $pdf->PMA_PDF_setXScale($this->x);
  550. $pdf->SetFont($ff, '');
  551. $pdf->SetTextColor(0);
  552. $pdf->SetFillColor(255);
  553. foreach ($this->fields AS $field) {
  554. // loic1 : PHP3 fix
  555. // if (in_array($field, $this->primary)) {
  556. if ($setcolor) {
  557. if (in_array($field, $this->primary)) {
  558. $pdf->SetFillColor(215, 121, 123);
  559. }
  560. if ($field == $this->displayfield) {
  561. $pdf->SetFillColor(142, 159, 224);
  562. }
  563. }
  564. if ($with_doc) {
  565. $pdf->SetLink($pdf->PMA_links['RT'][$this->table_name][$field], -1);
  566. } else {
  567. $pdf->PMA_links['doc'][$this->table_name][$field] = '';
  568. }
  569. $pdf->PMA_PDF_cellScale($this->width, $this->height_cell, ' ' . $field, 1, 1, 'L', $setcolor, $pdf->PMA_links['doc'][$this->table_name][$field]);
  570. $pdf->PMA_PDF_setXScale($this->x);
  571. $pdf->SetFillColor(255);
  572. } // end while
  573. /*if ($pdf->PageNo() > 1) {
  574. $pdf->PMA_PDF_die($GLOBALS['strScaleFactorSmall']);
  575. } */
  576. } // end of the "PMA_RT_Table_draw()" method
  577. /**
  578. * The "PMA_RT_Table" constructor
  579. *
  580. * @param string $ The table name
  581. * @param integer $ The font size
  582. * @param integer $ The max. with among tables
  583. * @global object The current PDF document
  584. * @global integer The current page number (from the
  585. * $cfg['Servers'][$i]['table_coords'] table)
  586. * @global array The relations settings
  587. * @global string The current db name
  588. * @access private
  589. * @see PMA_PDF, PMA_RT_Table::PMA_RT_Table_setWidth,
  590. PMA_RT_Table::PMA_RT_Table_setHeight
  591. */
  592. function __construct($table_name, $ff, &$same_wide_width, $show_keys)
  593. {
  594. global $pdf, $pdf_page_number, $cfgRelation, $db;
  595. $this->table_name = $table_name;
  596. $sql = 'DESCRIBE ' . PMA_backquote($table_name);
  597. $result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE);
  598. if (!$result || !PMA_DBI_num_rows($result)) {
  599. $pdf->PMA_PDF_die(sprintf($GLOBALS['strPdfInvalidTblName'], $table_name));
  600. }
  601. // load fields
  602. //check to see if it will load all fields or only the foreign keys
  603. if ($show_keys) {
  604. $indexes = PMA_Index::getFromTable($this->table_name, $db);
  605. $all_columns = array();
  606. foreach ($indexes as $index) {
  607. $all_columns = array_merge($all_columns, array_flip(array_keys($index->getColumns())));
  608. }
  609. $this->fields = array_keys($all_columns);
  610. } else {
  611. while ($row = PMA_DBI_fetch_row($result)) {
  612. $this->fields[] = $row[0];
  613. }
  614. }
  615. // height and width
  616. $this->PMA_RT_Table_setWidth($ff);
  617. $this->PMA_RT_Table_setHeight();
  618. if ($same_wide_width < $this->width) {
  619. $same_wide_width = $this->width;
  620. }
  621. // x and y
  622. $sql = 'SELECT x, y FROM '
  623. . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
  624. . ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
  625. . ' AND table_name = \'' . PMA_sqlAddslashes($table_name) . '\''
  626. . ' AND pdf_page_number = ' . $pdf_page_number;
  627. $result = PMA_query_as_cu($sql, false, PMA_DBI_QUERY_STORE);
  628. if (!$result || !PMA_DBI_num_rows($result)) {
  629. $pdf->PMA_PDF_die(sprintf($GLOBALS['strConfigureTableCoord'], $table_name));
  630. }
  631. list($this->x, $this->y) = PMA_DBI_fetch_row($result);
  632. $this->x = (double) $this->x;
  633. $this->y = (double) $this->y;
  634. // displayfield
  635. $this->displayfield = PMA_getDisplayField($db, $table_name);
  636. // index
  637. $result = PMA_DBI_query('SHOW INDEX FROM ' . PMA_backquote($table_name) . ';', null, PMA_DBI_QUERY_STORE);
  638. if (PMA_DBI_num_rows($result) > 0) {
  639. while ($row = PMA_DBI_fetch_assoc($result)) {
  640. if ($row['Key_name'] == 'PRIMARY') {
  641. $this->primary[] = $row['Column_name'];
  642. }
  643. }
  644. } // end if
  645. } // end of the "PMA_RT_Table()" method
  646. } // end class "PMA_RT_Table"
  647. /**
  648. * Draws relation links
  649. *
  650. * @access private
  651. * @see PMA_RT
  652. * @package phpMyAdmin
  653. */
  654. class PMA_RT_Relation {
  655. /**
  656. * Defines private properties
  657. */
  658. var $x_src, $y_src;
  659. var $src_dir ;
  660. var $dest_dir;
  661. var $x_dest, $y_dest;
  662. var $w_tick = 5;
  663. /**
  664. * Gets arrows coordinates
  665. *
  666. * @param string $ The current table name
  667. * @param string $ The relation column name
  668. * @return array Arrows coordinates
  669. * @access private
  670. */
  671. function PMA_RT_Relation_getXy($table, $column)
  672. {
  673. $pos = array_search($column, $table->fields);
  674. // x_left, x_right, y
  675. return array($table->x, $table->x + + $table->width, $table->y + ($pos + 1.5) * $table->height_cell);
  676. } // end of the "PMA_RT_Relation_getXy()" method
  677. /**
  678. * Do draws relation links
  679. *
  680. * @param boolean $ Whether to use one color per relation or not
  681. * @param integer $ The id of the link to draw
  682. * @global object The current PDF document
  683. * @access private
  684. * @see PMA_PDF
  685. */
  686. function PMA_RT_Relation_draw($change_color, $i)
  687. {
  688. global $pdf;
  689. if ($change_color) {
  690. $d = $i % 6;
  691. $j = ($i - $d) / 6;
  692. $j = $j % 4;
  693. $j++;
  694. $case = array(
  695. array(1, 0, 0),
  696. array(0, 1, 0),
  697. array(0, 0, 1),
  698. array(1, 1, 0),
  699. array(1, 0, 1),
  700. array(0, 1, 1)
  701. );
  702. list ($a, $b, $c) = $case[$d];
  703. $e = (1 - ($j - 1) / 6);
  704. $pdf->SetDrawColor($a * 255 * $e, $b * 255 * $e, $c * 255 * $e);
  705. } else {
  706. $pdf->SetDrawColor(0);
  707. } // end if... else...
  708. $pdf->PMA_PDF_setLineWidthScale(0.2);
  709. $pdf->PMA_PDF_lineScale($this->x_src, $this->y_src, $this->x_src + $this->src_dir * $this->w_tick, $this->y_src);
  710. $pdf->PMA_PDF_lineScale($this->x_dest + $this->dest_dir * $this->w_tick, $this->y_dest, $this->x_dest, $this->y_dest);
  711. $pdf->PMA_PDF_setLineWidthScale(0.1);
  712. $pdf->PMA_PDF_lineScale($this->x_src + $this->src_dir * $this->w_tick, $this->y_src, $this->x_dest + $this->dest_dir * $this->w_tick, $this->y_dest);
  713. // arrow
  714. $root2 = 2 * sqrt(2);
  715. $pdf->PMA_PDF_lineScale($this->x_src + $this->src_dir * $this->w_tick * 0.75, $this->y_src, $this->x_src + $this->src_dir * (0.75 - 1 / $root2) * $this->w_tick, $this->y_src + $this->w_tick / $root2);
  716. $pdf->PMA_PDF_lineScale($this->x_src + $this->src_dir * $this->w_tick * 0.75, $this->y_src, $this->x_src + $this->src_dir * (0.75 - 1 / $root2) * $this->w_tick, $this->y_src - $this->w_tick / $root2);
  717. $pdf->PMA_PDF_lineScale($this->x_dest + $this->dest_dir * $this->w_tick / 2, $this->y_dest, $this->x_dest + $this->dest_dir * (0.5 + 1 / $root2) * $this->w_tick, $this->y_dest + $this->w_tick / $root2);
  718. $pdf->PMA_PDF_lineScale($this->x_dest + $this->dest_dir * $this->w_tick / 2, $this->y_dest, $this->x_dest + $this->dest_dir * (0.5 + 1 / $root2) * $this->w_tick, $this->y_dest - $this->w_tick / $root2);
  719. $pdf->SetDrawColor(0);
  720. } // end of the "PMA_RT_Relation_draw()" method
  721. /**
  722. * The "PMA_RT_Relation" constructor
  723. *
  724. * @param string $ The master table name
  725. * @param string $ The relation field in the master table
  726. * @param string $ The foreign table name
  727. * @param string $ The relation field in the foreign table
  728. * @access private
  729. * @see PMA_RT_Relation::PMA_RT_Relation_getXy
  730. */
  731. function __construct($master_table, $master_field, $foreign_table, $foreign_field)
  732. {
  733. $src_pos = $this->PMA_RT_Relation_getXy($master_table, $master_field);
  734. $dest_pos = $this->PMA_RT_Relation_getXy($foreign_table, $foreign_field);
  735. $src_left = $src_pos[0] - $this->w_tick;
  736. $src_right = $src_pos[1] + $this->w_tick;
  737. $dest_left = $dest_pos[0] - $this->w_tick;
  738. $dest_right = $dest_pos[1] + $this->w_tick;
  739. $d1 = abs($src_left - $dest_left);
  740. $d2 = abs($src_right - $dest_left);
  741. $d3 = abs($src_left - $dest_right);
  742. $d4 = abs($src_right - $dest_right);
  743. $d = min($d1, $d2, $d3, $d4);
  744. if ($d == $d1) {
  745. $this->x_src = $src_pos[0];
  746. $this->src_dir = -1;
  747. $this->x_dest = $dest_pos[0];
  748. $this->dest_dir = -1;
  749. } elseif ($d == $d2) {
  750. $this->x_src = $src_pos[1];
  751. $this->src_dir = 1;
  752. $this->x_dest = $dest_pos[0];
  753. $this->dest_dir = -1;
  754. } elseif ($d == $d3) {
  755. $this->x_src = $src_pos[0];
  756. $this->src_dir = -1;
  757. $this->x_dest = $dest_pos[1];
  758. $this->dest_dir = 1;
  759. } else {
  760. $this->x_src = $src_pos[1];
  761. $this->src_dir = 1;
  762. $this->x_dest = $dest_pos[1];
  763. $this->dest_dir = 1;
  764. }
  765. $this->y_src = $src_pos[2];
  766. $this->y_dest = $dest_pos[2];
  767. } // end of the "PMA_RT_Relation()" method
  768. } // end of the "PMA_RT_Relation" class
  769. /**
  770. * Draws and send the database schema
  771. *
  772. * @access public
  773. * @see PMA_PDF
  774. * @package phpMyAdmin
  775. */
  776. class PMA_RT {
  777. /**
  778. * Defines private properties
  779. */
  780. var $tables = array();
  781. var $relations = array();
  782. var $ff = PMA_PDF_FONT;
  783. var $x_max = 0;
  784. var $y_max = 0;
  785. var $scale;
  786. var $x_min = 100000;
  787. var $y_min = 100000;
  788. var $t_marg = 10;
  789. var $b_marg = 10;
  790. var $l_marg = 10;
  791. var $r_marg = 10;
  792. var $tablewidth;
  793. var $same_wide = 0;
  794. /**
  795. * Sets X and Y minimum and maximum for a table cell
  796. *
  797. * @param string $ The table name
  798. * @access private
  799. */
  800. function PMA_RT_setMinMax($table)
  801. {
  802. $this->x_max = max($this->x_max, $table->x + $table->width);
  803. $this->y_max = max($this->y_max, $table->y + $table->height);
  804. $this->x_min = min($this->x_min, $table->x);
  805. $this->y_min = min($this->y_min, $table->y);
  806. } // end of the "PMA_RT_setMinMax()" method
  807. /**
  808. * Defines relation objects
  809. *
  810. * @param string $ The master table name
  811. * @param string $ The relation field in the master table
  812. * @param string $ The foreign table name
  813. * @param string $ The relation field in the foreign table
  814. * @access private
  815. * @see PMA_RT_setMinMax
  816. */
  817. function PMA_RT_addRelation($master_table, $master_field, $foreign_table, $foreign_field)
  818. {
  819. if (!isset($this->tables[$master_table])) {
  820. $this->tables[$master_table] = new PMA_RT_Table($master_table, $this->ff, $this->tablewidth);
  821. $this->PMA_RT_setMinMax($this->tables[$master_table]);
  822. }
  823. if (!isset($this->tables[$foreign_table])) {
  824. $this->tables[$foreign_table] = new PMA_RT_Table($foreign_table, $this->ff, $this->tablewidth);
  825. $this->PMA_RT_setMinMax($this->tables[$foreign_table]);
  826. }
  827. $this->relations[] = new PMA_RT_Relation($this->tables[$master_table], $master_field, $this->tables[$foreign_table], $foreign_field);
  828. } // end of the "PMA_RT_addRelation()" method
  829. /**
  830. * Draws the grid
  831. *
  832. * @global object the current PMA_PDF instance
  833. * @access private
  834. * @see PMA_PDF
  835. */
  836. function PMA_RT_strokeGrid()
  837. {
  838. global $pdf;
  839. $pdf->SetMargins(0, 0);
  840. $pdf->SetDrawColor(200, 200, 200);
  841. // Draws horizontal lines
  842. for ($l = 0; $l < 21; $l++) {
  843. $pdf->line(0, $l * 10, $pdf->fh, $l * 10);
  844. // Avoid duplicates
  845. if ($l > 0) {
  846. $pdf->SetXY(0, $l * 10);
  847. $label = (string) sprintf('%.0f', ($l * 10 - $this->t_marg) * $this->scale + $this->y_min);
  848. $pdf->Cell(5, 5, ' ' . $label);
  849. } // end if
  850. } // end for
  851. // Draws vertical lines
  852. for ($j = 0; $j < 30 ;$j++) {
  853. $pdf->line($j * 10, 0, $j * 10, $pdf->fw);
  854. $pdf->SetXY($j * 10, 0);
  855. $label = (string) sprintf('%.0f', ($j * 10 - $this->l_marg) * $this->scale + $this->x_min);
  856. $pdf->Cell(5, 7, $label);
  857. } // end for
  858. } // end of the "PMA_RT_strokeGrid()" method
  859. /**
  860. * Draws relation arrows
  861. *
  862. * @param boolean $ Whether to use one color per relation or not
  863. * @access private
  864. * @see PMA_RT_Relation::PMA_RT_Relation_draw()
  865. */
  866. function PMA_RT_drawRelations($change_color)
  867. {
  868. $i = 0;
  869. foreach ($this->relations AS $relation) {
  870. $relation->PMA_RT_Relation_draw($change_color, $i);
  871. $i++;
  872. } // end while
  873. } // end of the "PMA_RT_drawRelations()" method
  874. /**
  875. * Draws tables
  876. *
  877. * @param boolean $ Whether to display table position or not
  878. * @access private
  879. * @see PMA_RT_Table::PMA_RT_Table_draw()
  880. */
  881. function PMA_RT_drawTables($show_info, $draw_color = 0)
  882. {
  883. foreach ($this->tables AS $table) {
  884. $table->PMA_RT_Table_draw($show_info, $this->ff, $draw_color);
  885. }
  886. } // end of the "PMA_RT_drawTables()" method
  887. /**
  888. * Ouputs the PDF document to a file
  889. *
  890. * @global object The current PDF document
  891. * @global string The current database name
  892. * @global integer The current page number (from the
  893. * $cfg['Servers'][$i]['table_coords'] table)
  894. * @access private
  895. * @see PMA_PDF
  896. */
  897. function PMA_RT_showRt()
  898. {
  899. global $pdf, $db, $pdf_page_number, $cfgRelation;
  900. $pdf->SetFontSize(14);
  901. $pdf->SetLineWidth(0.2);
  902. $pdf->SetDisplayMode('fullpage');
  903. // Get the name of this pdfpage to use as filename (Mike Beck)
  904. $_name_sql = 'SELECT page_descr FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['pdf_pages'])
  905. . ' WHERE page_nr = ' . $pdf_page_number;
  906. $_name_rs = PMA_query_as_cu($_name_sql);
  907. if ($_name_rs) {
  908. $_name_row = PMA_DBI_fetch_row($_name_rs);
  909. $filename = $_name_row[0] . '.pdf';
  910. }
  911. // i don't know if there is a chance for this to happen, but rather be on the safe side:
  912. if (empty($filename)) {
  913. $filename = $pdf_page_number . '.pdf';
  914. }
  915. // $pdf->Output($db . '_' . $filename, TRUE);
  916. $pdf->Output($db . '_' . $filename, 'I'); // destination: Inline
  917. } // end of the "PMA_RT_showRt()" method
  918. /**
  919. * The "PMA_RT" constructor
  920. *
  921. * @param mixed $ The scaling factor
  922. * @param integer $ The page number to draw (from the
  923. * $cfg['Servers'][$i]['table_coords'] table)
  924. * @param boolean $ Whether to display table position or not
  925. * @param boolean $ Was originally whether to use one color per
  926. * relation or not, now enables/disables color
  927. * everywhere, due to some problems printing with color
  928. * @param boolean $ Whether to draw grids or not
  929. * @param boolean $ Whether all tables should have the same width or not
  930. * @param boolean $ Wheter to show all field or only the keys
  931. * @global object The current PDF document
  932. * @global string The current db name
  933. * @global array The relations settings
  934. * @access private
  935. * @see PMA_PDF
  936. */
  937. function __construct($which_rel, $show_info = 0, $change_color = 0, $show_grid = 0, $all_tab_same_wide = 0, $orientation = 'L', $paper = 'A4', $show_keys = 0)
  938. {
  939. global $pdf, $db, $cfgRelation, $with_doc;
  940. $this->same_wide = $all_tab_same_wide;
  941. // Initializes a new document
  942. $pdf = new PMA_PDF('L', 'mm', $paper);
  943. $pdf->SetTitle(sprintf($GLOBALS['strPdfDbSchema'], $GLOBALS['db'], $which_rel));
  944. $pdf->setCMargin(0);
  945. $pdf->Open();
  946. $pdf->SetAuthor('phpMyAdmin ' . PMA_VERSION);
  947. $pdf->AliasNbPages();
  948. $pdf->AddFont('DejaVuSans', '', 'dejavusans.php');
  949. $pdf->AddFont('DejaVuSans', 'B', 'dejavusansb.php');
  950. $pdf->AddFont('DejaVuSerif', '', 'dejavuserif.php');
  951. $pdf->AddFont('DejaVuSerif', 'B', 'dejavuserifb.php');
  952. $this->ff = PMA_PDF_FONT;
  953. $pdf->SetFont($this->ff, '', 14);
  954. $pdf->SetAutoPageBreak('auto');
  955. // Gets tables on this page
  956. $tab_sql = 'SELECT table_name FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
  957. . ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
  958. . ' AND pdf_page_number = ' . $which_rel;
  959. $tab_rs = PMA_query_as_cu($tab_sql, null, PMA_DBI_QUERY_STORE);
  960. if (!$tab_rs || !PMA_DBI_num_rows($tab_rs) > 0) {
  961. $pdf->PMA_PDF_die($GLOBALS['strPdfNoTables']);
  962. // die('No tables');
  963. } while ($curr_table = @PMA_DBI_fetch_assoc($tab_rs)) {
  964. $alltables[] = PMA_sqlAddslashes($curr_table['table_name']);
  965. // $intable = '\'' . implode('\', \'', $alltables) . '\'';
  966. }
  967. // make doc //
  968. if ($with_doc) {
  969. $pdf->SetAutoPageBreak('auto', 15);
  970. $pdf->setCMargin(1);
  971. PMA_RT_DOC($alltables);
  972. $pdf->SetAutoPageBreak('auto');
  973. $pdf->setCMargin(0);
  974. }
  975. $pdf->Addpage();
  976. if ($with_doc) {
  977. $pdf->SetLink($pdf->PMA_links['RT']['-'], -1);
  978. $pdf->Bookmark($GLOBALS['strRelationalSchema']);
  979. $pdf->SetAlias('{00}', $pdf->PageNo()) ;
  980. $this->t_marg = 18;
  981. $this->b_marg = 18;
  982. }
  983. /* snip */
  984. foreach ($alltables AS $table) {
  985. if (!isset($this->tables[$table])) {
  986. $this->tables[$table] = new PMA_RT_Table($table, $this->ff, $this->tablewidth, $show_keys);
  987. }
  988. if ($this->same_wide) {
  989. $this->tables[$table]->width = $this->tablewidth;
  990. }
  991. $this->PMA_RT_setMinMax($this->tables[$table]);
  992. }
  993. // Defines the scale factor
  994. $this->scale = ceil(
  995. max(
  996. ($this->x_max - $this->x_min) / ($pdf->getFh() - $this->r_marg - $this->l_marg),
  997. ($this->y_max - $this->y_min) / ($pdf->getFw() - $this->t_marg - $this->b_marg))
  998. * 100) / 100;
  999. $pdf->PMA_PDF_setScale($this->scale, $this->x_min, $this->y_min, $this->l_marg, $this->t_marg);
  1000. // Builds and save the PDF document
  1001. $pdf->PMA_PDF_setLineWidthScale(0.1);
  1002. if ($show_grid) {
  1003. $pdf->SetFontSize(10);
  1004. $this->PMA_RT_strokeGrid();
  1005. }
  1006. $pdf->PMA_PDF_setFontSizeScale(14);
  1007. // $sql = 'SELECT * FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['relation'])
  1008. // . ' WHERE master_db = \'' . PMA_sqlAddslashes($db) . '\' '
  1009. // . ' AND foreign_db = \'' . PMA_sqlAddslashes($db) . '\' '
  1010. // . ' AND master_table IN (' . $intable . ')'
  1011. // . ' AND foreign_table IN (' . $intable . ')';
  1012. // $result = PMA_query_as_cu($sql);
  1013. // lem9:
  1014. // previous logic was checking master tables and foreign tables
  1015. // but I think that looping on every table of the pdf page as a master
  1016. // and finding its foreigns is OK (then we can support innodb)
  1017. $seen_a_relation = false;
  1018. foreach ($alltables AS $one_table) {
  1019. $exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
  1020. if ($exist_rel) {
  1021. $seen_a_relation = true;
  1022. foreach ($exist_rel AS $master_field => $rel) {
  1023. // put the foreign table on the schema only if selected
  1024. // by the user
  1025. // (do not use array_search() because we would have to
  1026. // to do a === FALSE and this is not PHP3 compatible)
  1027. if (in_array($rel['foreign_table'], $alltables)) {
  1028. $this->PMA_RT_addRelation($one_table, $master_field, $rel['foreign_table'], $rel['foreign_field']);
  1029. }
  1030. } // end while
  1031. } // end if
  1032. } // end while
  1033. // loic1: also show tables without relations
  1034. // $norelations = TRUE;
  1035. // if ($result && PMA_DBI_num_rows($result) > 0) {
  1036. // $norelations = FALSE;
  1037. // while ($row = PMA_DBI_fetch_assoc($result)) {
  1038. // $this->PMA_RT_addRelation($row['master_table'], $row['master_field'], $row['foreign_table'], $row['foreign_field']);
  1039. // }
  1040. // }
  1041. // if ($norelations == FALSE) {
  1042. if ($seen_a_relation) {
  1043. $this->PMA_RT_drawRelations($change_color);
  1044. }
  1045. $this->PMA_RT_drawTables($show_info, $change_color);
  1046. $this->PMA_RT_showRt();
  1047. } // end of the "PMA_RT()" method
  1048. } // end of the "PMA_RT" class
  1049. function PMA_RT_DOC($alltables)
  1050. {
  1051. global $db, $pdf, $orientation, $paper;
  1052. // TOC
  1053. $pdf->addpage($GLOBALS['orientation']);
  1054. $pdf->Cell(0, 9, $GLOBALS['strTableOfContents'], 1, 0, 'C');
  1055. $pdf->Ln(15);
  1056. $i = 1;
  1057. foreach ($alltables AS $table) {
  1058. $pdf->PMA_links['doc'][$table]['-'] = $pdf->AddLink();
  1059. $pdf->SetX(10);
  1060. // $pdf->Ln(1);
  1061. $pdf->Cell(0, 6, $GLOBALS['strPageNumber'] . ' {' . sprintf("%02d", $i) . '}', 0, 0, 'R', 0, $pdf->PMA_links['doc'][$table]['-']);
  1062. $pdf->SetX(10);
  1063. $pdf->Cell(0, 6, $i . ' ' . $table, 0, 1, 'L', 0, $pdf->PMA_links['doc'][$table]['-']);
  1064. // $pdf->Ln(1);
  1065. $result = PMA_DBI_query('SHOW FIELDS FROM ' . PMA_backquote($table) . ';');
  1066. while ($row = PMA_DBI_fetch_assoc($result)) {
  1067. $pdf->SetX(20);
  1068. $field_name = $row['Field'];
  1069. $pdf->PMA_links['doc'][$table][$field_name] = $pdf->AddLink();
  1070. // $pdf->Cell(0, 6, $field_name,0,1,'L',0, $pdf->PMA_links['doc'][$table][$field_name]);
  1071. }
  1072. $lasttable = $table;
  1073. $i++;
  1074. }
  1075. $pdf->PMA_links['RT']['-'] = $pdf->AddLink();
  1076. $pdf->SetX(10);
  1077. $pdf->Cell(0, 6, $GLOBALS['strPageNumber'] . ' {00}', 0, 0, 'R', 0, $pdf->PMA_links['doc'][$lasttable]['-']);
  1078. $pdf->SetX(10);
  1079. $pdf->Cell(0, 6, $i . ' ' . $GLOBALS['strRelationalSchema'], 0, 1, 'L', 0, $pdf->PMA_links['RT']['-']);
  1080. $z = 0;
  1081. foreach ($alltables AS $table) {
  1082. $z++;
  1083. $pdf->addpage($GLOBALS['orientation']);
  1084. $pdf->Bookmark($table);
  1085. $pdf->SetAlias('{' . sprintf("%02d", $z) . '}', $pdf->PageNo()) ;
  1086. $pdf->PMA_links['RT'][$table]['-'] = $pdf->AddLink();
  1087. $pdf->SetLink($pdf->PMA_links['doc'][$table]['-'], -1);
  1088. $pdf->SetFont('', 'B', 18);
  1089. $pdf->Cell(0, 8, $z . ' ' . $table, 1, 1, 'C', 0, $pdf->PMA_links['RT'][$table]['-']);
  1090. $pdf->SetFont('', '', 8);
  1091. $pdf->ln();
  1092. $cfgRelation = PMA_getRelationsParam();
  1093. $comments = PMA_getComments($db, $table);
  1094. if ($cfgRelation['mimework']) {
  1095. $mime_map = PMA_getMIME($db, $table, true);
  1096. }
  1097. /**
  1098. * Gets table informations
  1099. */
  1100. $showtable = PMA_Table::sGetStatusInfo($db, $table);
  1101. $num_rows = (isset($showtable['Rows']) ? $showtable['Rows'] : 0);
  1102. $show_comment = (isset($showtable['Comment']) ? $showtable['Comment'] : '');
  1103. $create_time = (isset($showtable['Create_time']) ? PMA_localisedDate(strtotime($showtable['Create_time'])) : '');
  1104. $update_time = (isset($showtable['Update_time']) ? PMA_localisedDate(strtotime($showtable['Update_time'])) : '');
  1105. $check_time = (isset($showtable['Check_time']) ? PMA_localisedDate(strtotime($showtable['Check_time'])) : '');
  1106. /**
  1107. * Gets table keys and retains them
  1108. */
  1109. $result = PMA_DBI_query('SHOW KEYS FROM ' . PMA_backquote($table) . ';');
  1110. $primary = '';
  1111. $indexes = array();
  1112. $lastIndex = '';
  1113. $indexes_info = array();
  1114. $indexes_data = array();
  1115. $pk_array = array(); // will be use to emphasis prim. keys in the table
  1116. // view
  1117. while ($row = PMA_DBI_fetch_assoc($result)) {
  1118. // Backups the list of primary keys
  1119. if ($row['Key_name'] == 'PRIMARY') {
  1120. $primary .= $row['Column_name'] . ', ';
  1121. $pk_array[$row['Column_name']] = 1;
  1122. }
  1123. // Retains keys informations
  1124. if ($row['Key_name'] != $lastIndex) {
  1125. $indexes[] = $row['Key_name'];
  1126. $lastIndex = $row['Key_name'];
  1127. }
  1128. $indexes_info[$row['Key_name']]['Sequences'][] = $row['Seq_in_index'];
  1129. $indexes_info[$row['Key_name']]['Non_unique'] = $row['Non_unique'];
  1130. if (isset($row['Cardinality'])) {
  1131. $indexes_info[$row['Key_name']]['Cardinality'] = $row['Cardinality'];
  1132. }
  1133. // I don't know what does following column mean....
  1134. // $indexes_info[$row['Key_name']]['Packed'] = $row['Packed'];
  1135. $indexes_info[$row['Key_name']]['Comment'] = $row['Comment'];
  1136. $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Column_name'] = $row['Column_name'];
  1137. if (isset($row['Sub_part'])) {
  1138. $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Sub_part'] = $row['Sub_part'];
  1139. }
  1140. } // end while
  1141. if ($result) {
  1142. PMA_DBI_free_result($result);
  1143. }
  1144. /**
  1145. * Gets fields properties
  1146. */
  1147. $result = PMA_DBI_query('SHOW FIELDS FROM ' . PMA_backquote($table) . ';', null, PMA_DBI_QUERY_STORE);
  1148. $fields_cnt = PMA_DBI_num_rows($result);
  1149. // Check if we can use Relations (Mike Beck)
  1150. if (!empty($cfgRelation['relation'])) {
  1151. // Find which tables are related with the current one and write it in
  1152. // an array
  1153. $res_rel = PMA_getForeigners($db, $table);
  1154. if (count($res_rel) > 0) {
  1155. $have_rel = true;
  1156. } else {
  1157. $have_rel = false;
  1158. }
  1159. } else {
  1160. $have_rel = false;
  1161. } // end if
  1162. /**
  1163. * Displays the comments of the table if MySQL >= 3.23
  1164. */
  1165. $break = false;
  1166. if (!empty($show_comment)) {
  1167. $pdf->Cell(0, 3, $GLOBALS['strTableComments'] . ' : ' . $show_comment, 0, 1);
  1168. $break = true;
  1169. }
  1170. if (!empty($create_time)) {
  1171. $pdf->Cell(0, 3, $GLOBALS['strStatCreateTime'] . ': ' . $create_time, 0, 1);
  1172. $break = true;
  1173. }
  1174. if (!empty($update_time)) {
  1175. $pdf->Cell(0, 3, $GLOBALS['strStatUpdateTime'] . ': ' . $update_time, 0, 1);
  1176. $break = true;
  1177. }
  1178. if (!empty($check_time)) {
  1179. $pdf->Cell(0, 3, $GLOBALS['strStatCheckTime'] . ': ' . $check_time, 0, 1);
  1180. $break = true;
  1181. }
  1182. if ($break == true) {
  1183. $pdf->Cell(0, 3, '', 0, 1);
  1184. $pdf->Ln();
  1185. }
  1186. $pdf->SetFont('', 'B');
  1187. if (isset($orientation) && $orientation == 'L') {
  1188. $pdf->Cell(25, 8, ucfirst($GLOBALS['strField']), 1, 0, 'C');
  1189. $pdf->Cell(20, 8, ucfirst($GLOBALS['strType']), 1, 0, 'C');
  1190. $pdf->Cell(20, 8, ucfirst($GLOBALS['strAttr']), 1, 0, 'C');
  1191. $pdf->Cell(10, 8, ucfirst($GLOBALS['strNull']), 1, 0, 'C');
  1192. $pdf->Cell(20, 8, ucfirst($GLOBALS['strDefault']), 1, 0, 'C');
  1193. $pdf->Cell(25, 8, ucfirst($GLOBALS['strExtra']), 1, 0, 'C');
  1194. $pdf->Cell(45, 8, ucfirst($GLOBALS['strLinksTo']), 1, 0, 'C');
  1195. if ($paper == 'A4') {
  1196. $comments_width = 67;
  1197. } else {
  1198. // this is really intended for 'letter'
  1199. /**
  1200. * @todo find optimal width for all formats
  1201. */
  1202. $comments_width = 50;
  1203. }
  1204. $pdf->Cell($comments_width, 8, ucfirst($GLOBALS['strComments']), 1, 0, 'C');
  1205. $pdf->Cell(45, 8, 'MIME', 1, 1, 'C');
  1206. $pdf->SetWidths(array(25, 20, 20, 10, 20, 25, 45, $comments_width, 45));
  1207. } else {
  1208. $pdf->Cell(20, 8, ucfirst($GLOBALS['strField']), 1, 0, 'C');
  1209. $pdf->Cell(20, 8, ucfirst($GLOBALS['strType']), 1, 0, 'C');
  1210. $pdf->Cell(20, 8, ucfirst($GLOBALS['strAttr']), 1, 0, 'C');
  1211. $pdf->Cell(10, 8, ucfirst($GLOBALS['strNull']), 1, 0, 'C');
  1212. $pdf->Cell(15, 8, ucfirst($GLOBALS['strDefault']), 1, 0, 'C');
  1213. $pdf->Cell(15, 8, ucfirst($GLOBALS['strExtra']), 1, 0, 'C');
  1214. $pdf->Cell(30, 8, ucfirst($GLOBALS['strLinksTo']), 1, 0, 'C');
  1215. $pdf->Cell(30, 8, ucfirst($GLOBALS['strComments']), 1, 0, 'C');
  1216. $pdf->Cell(30, 8, 'MIME', 1, 1, 'C');
  1217. $pdf->SetWidths(array(20, 20, 20, 10, 15, 15, 30, 30, 30));
  1218. }
  1219. $pdf->SetFont('', '');
  1220. while ($row = PMA_DBI_fetch_assoc($result)) {
  1221. $type = $row['Type'];
  1222. // reformat mysql query output - staybyte - 9. June 2001
  1223. // loic1: set or enum types: slashes single quotes inside options
  1224. if (preg_match('@^(set|enum)\((.+)\)$@i', $type, $tmp)) {
  1225. $tmp[2] = substr(preg_replace("@([^,])''@", "\\1\\'", ',' . $tmp[2]), 1);
  1226. $type = $tmp[1] . '(' . str_replace(',', ', ', $tmp[2]) . ')';
  1227. $type_nowrap = '';
  1228. $binary = 0;
  1229. $unsigned = 0;
  1230. $zerofill = 0;
  1231. } else {
  1232. $type_nowrap = ' nowrap="nowrap"';
  1233. $type = preg_replace('@BINARY@i', '', $type);
  1234. $type = preg_replace('@ZEROFILL@i', '', $type);
  1235. $type = preg_replace('@UNSIGNED@i', '', $type);
  1236. if (empty($type)) {
  1237. $type = '&nbsp;';
  1238. }
  1239. $binary = stristr($row['Type'], 'BINARY');
  1240. $unsigned = stristr($row['Type'], 'UNSIGNED');
  1241. $zerofill = stristr($row['Type'], 'ZEROFILL');
  1242. }
  1243. $strAttribute = ' ';
  1244. if ($binary) {
  1245. $strAttribute = 'BINARY';
  1246. }
  1247. if ($unsigned) {
  1248. $strAttribute = 'UNSIGNED';
  1249. }
  1250. if ($zerofill) {
  1251. $strAttribute = 'UNSIGNED ZEROFILL';
  1252. }
  1253. if (!isset($row['Default'])) {
  1254. if ($row['Null'] != '' && $row['Null'] != 'NO') {
  1255. $row['Default'] = 'NULL';
  1256. }
  1257. }
  1258. $field_name = $row['Field'];
  1259. // $pdf->Ln();
  1260. $pdf->PMA_links['RT'][$table][$field_name] = $pdf->AddLink();
  1261. $pdf->Bookmark($field_name, 1, -1);
  1262. $pdf->SetLink($pdf->PMA_links['doc'][$table][$field_name], -1);
  1263. $pdf_row = array($field_name,
  1264. $type,
  1265. $strAttribute,
  1266. ($row['Null'] == '' || $row['Null'] == 'NO') ? $GLOBALS['strNo'] : $GLOBALS['strYes'],
  1267. ((isset($row['Default'])) ? $row['Default'] : ''),
  1268. $row['Extra'],
  1269. ((isset($res_rel[$field_name])) ? $res_rel[$f

Large files files are truncated, but you can click here to view the full file