Pdf_Relation_Schema.class.php 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * PDF schema handling
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. if (! defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. /**
  12. * block attempts to directly run this script
  13. */
  14. if (getcwd() == dirname(__FILE__)) {
  15. die('Attack stopped');
  16. }
  17. require_once 'Export_Relation_Schema.class.php';
  18. require_once './libraries/PDF.class.php';
  19. /**
  20. * Extends the "TCPDF" class and helps
  21. * in developing the structure of PDF Schema Export
  22. *
  23. * @access public
  24. * @package PhpMyAdmin
  25. * @see TCPDF
  26. */
  27. class PMA_Schema_PDF extends PMA_PDF
  28. {
  29. /**
  30. * Defines properties
  31. */
  32. var $_xMin;
  33. var $_yMin;
  34. var $leftMargin = 10;
  35. var $topMargin = 10;
  36. var $scale;
  37. var $PMA_links;
  38. var $Outlines = array();
  39. var $def_outlines;
  40. var $widths;
  41. private $_ff = PMA_PDF_FONT;
  42. /**
  43. * Sets the value for margins
  44. *
  45. * @param float $c_margin margin
  46. *
  47. * @return void
  48. */
  49. public function setCMargin($c_margin)
  50. {
  51. $this->cMargin = $c_margin;
  52. }
  53. /**
  54. * Sets the scaling factor, defines minimum coordinates and margins
  55. *
  56. * @param float $scale The scaling factor
  57. * @param float $xMin The minimum X coordinate
  58. * @param float $yMin The minimum Y coordinate
  59. * @param float $leftMargin The left margin
  60. * @param float $topMargin The top margin
  61. *
  62. * @access public
  63. *
  64. * @return void
  65. */
  66. function setScale($scale = 1, $xMin = 0, $yMin = 0,
  67. $leftMargin = -1, $topMargin = -1
  68. ) {
  69. $this->scale = $scale;
  70. $this->_xMin = $xMin;
  71. $this->_yMin = $yMin;
  72. if ($this->leftMargin != -1) {
  73. $this->leftMargin = $leftMargin;
  74. }
  75. if ($this->topMargin != -1) {
  76. $this->topMargin = $topMargin;
  77. }
  78. }
  79. /**
  80. * Outputs a scaled cell
  81. *
  82. * @param float $w The cell width
  83. * @param float $h The cell height
  84. * @param string $txt The text to output
  85. * @param mixed $border Whether to add borders or not
  86. * @param integer $ln Where to put the cursor once the output is done
  87. * @param string $align Align mode
  88. * @param integer $fill Whether to fill the cell with a color or not
  89. * @param string $link Link
  90. *
  91. * @access public
  92. *
  93. * @return void
  94. *
  95. * @see TCPDF::Cell()
  96. */
  97. function cellScale($w, $h = 0, $txt = '', $border = 0, $ln = 0,
  98. $align = '', $fill = 0, $link = ''
  99. ) {
  100. $h = $h / $this->scale;
  101. $w = $w / $this->scale;
  102. $this->Cell($w, $h, $txt, $border, $ln, $align, $fill, $link);
  103. }
  104. /**
  105. * Draws a scaled line
  106. *
  107. * @param float $x1 The horizontal position of the starting point
  108. * @param float $y1 The vertical position of the starting point
  109. * @param float $x2 The horizontal position of the ending point
  110. * @param float $y2 The vertical position of the ending point
  111. *
  112. * @access public
  113. *
  114. * @return void
  115. *
  116. * @see TCPDF::Line()
  117. */
  118. function lineScale($x1, $y1, $x2, $y2)
  119. {
  120. $x1 = ($x1 - $this->_xMin) / $this->scale + $this->leftMargin;
  121. $y1 = ($y1 - $this->_yMin) / $this->scale + $this->topMargin;
  122. $x2 = ($x2 - $this->_xMin) / $this->scale + $this->leftMargin;
  123. $y2 = ($y2 - $this->_yMin) / $this->scale + $this->topMargin;
  124. $this->Line($x1, $y1, $x2, $y2);
  125. }
  126. /**
  127. * Sets x and y scaled positions
  128. *
  129. * @param float $x The x position
  130. * @param float $y The y position
  131. *
  132. * @access public
  133. *
  134. * @return void
  135. *
  136. * @see TCPDF::SetXY()
  137. */
  138. function setXyScale($x, $y)
  139. {
  140. $x = ($x - $this->_xMin) / $this->scale + $this->leftMargin;
  141. $y = ($y - $this->_yMin) / $this->scale + $this->topMargin;
  142. $this->SetXY($x, $y);
  143. }
  144. /**
  145. * Sets the X scaled positions
  146. *
  147. * @param float $x The x position
  148. *
  149. * @access public
  150. *
  151. * @return void
  152. *
  153. * @see TCPDF::SetX()
  154. */
  155. function setXScale($x)
  156. {
  157. $x = ($x - $this->_xMin) / $this->scale + $this->leftMargin;
  158. $this->SetX($x);
  159. }
  160. /**
  161. * Sets the scaled font size
  162. *
  163. * @param float $size The font size (in points)
  164. *
  165. * @access public
  166. *
  167. * @return void
  168. *
  169. * @see TCPDF::SetFontSize()
  170. */
  171. function setFontSizeScale($size)
  172. {
  173. // Set font size in points
  174. $size = $size / $this->scale;
  175. $this->SetFontSize($size);
  176. }
  177. /**
  178. * Sets the scaled line width
  179. *
  180. * @param float $width The line width
  181. *
  182. * @access public
  183. *
  184. * @return void
  185. *
  186. * @see TCPDF::SetLineWidth()
  187. */
  188. function setLineWidthScale($width)
  189. {
  190. $width = $width / $this->scale;
  191. $this->SetLineWidth($width);
  192. }
  193. /**
  194. * This method is used to render the page header.
  195. *
  196. * @return void
  197. *
  198. * @see TCPDF::Header()
  199. */
  200. function Header()
  201. {
  202. // We only show this if we find something in the new pdf_pages table
  203. // This function must be named "Header" to work with the TCPDF library
  204. global $cfgRelation, $db, $pdf_page_number, $with_doc;
  205. if ($with_doc) {
  206. $test_query = 'SELECT * FROM '
  207. . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
  208. . PMA_Util::backquote($cfgRelation['pdf_pages'])
  209. . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
  210. . ' AND page_nr = \'' . $pdf_page_number . '\'';
  211. $test_rs = PMA_queryAsControlUser($test_query);
  212. $pages = @PMA_DBI_fetch_assoc($test_rs);
  213. $this->SetFont($this->_ff, 'B', 14);
  214. $this->Cell(0, 6, ucfirst($pages['page_descr']), 'B', 1, 'C');
  215. $this->SetFont($this->_ff, '');
  216. $this->Ln();
  217. }
  218. }
  219. /**
  220. * This function must be named "Footer" to work with the TCPDF library
  221. *
  222. * @return void
  223. *
  224. * @see PMA_PDF::Footer()
  225. */
  226. function Footer()
  227. {
  228. global $with_doc;
  229. if ($with_doc) {
  230. parent::Footer();
  231. }
  232. }
  233. /**
  234. * Sets widths
  235. *
  236. * @param array $w array of widths
  237. *
  238. * @return void
  239. */
  240. function SetWidths($w)
  241. {
  242. // column widths
  243. $this->widths = $w;
  244. }
  245. /**
  246. * Generates table row.
  247. *
  248. * @param array $data Data for table
  249. * @param array $links Links for table cells
  250. *
  251. * @return void
  252. */
  253. function Row($data, $links)
  254. {
  255. // line height
  256. $nb = 0;
  257. $data_cnt = count($data);
  258. for ($i = 0;$i < $data_cnt;$i++) {
  259. $nb = max($nb, $this->NbLines($this->widths[$i], $data[$i]));
  260. }
  261. $il = $this->FontSize;
  262. $h = ($il + 1) * $nb;
  263. // page break if necessary
  264. $this->CheckPageBreak($h);
  265. // draw the cells
  266. $data_cnt = count($data);
  267. for ($i = 0;$i < $data_cnt;$i++) {
  268. $w = $this->widths[$i];
  269. // save current position
  270. $x = $this->GetX();
  271. $y = $this->GetY();
  272. // draw the border
  273. $this->Rect($x, $y, $w, $h);
  274. if (isset($links[$i])) {
  275. $this->Link($x, $y, $w, $h, $links[$i]);
  276. }
  277. // print text
  278. $this->MultiCell($w, $il + 1, $data[$i], 0, 'L');
  279. // go to right side
  280. $this->SetXY($x + $w, $y);
  281. }
  282. // go to line
  283. $this->Ln($h);
  284. }
  285. /**
  286. * Compute number of lines used by a multicell of width w
  287. *
  288. * @param int $w width
  289. * @param string $txt text
  290. *
  291. * @return int
  292. */
  293. function NbLines($w, $txt)
  294. {
  295. $cw = &$this->CurrentFont['cw'];
  296. if ($w == 0) {
  297. $w = $this->w - $this->rMargin - $this->x;
  298. }
  299. $wmax = ($w-2 * $this->cMargin) * 1000 / $this->FontSize;
  300. $s = str_replace("\r", '', $txt);
  301. $nb = strlen($s);
  302. if ($nb > 0 and $s[$nb-1] == "\n") {
  303. $nb--;
  304. }
  305. $sep = -1;
  306. $i = 0;
  307. $j = 0;
  308. $l = 0;
  309. $nl = 1;
  310. while ($i < $nb) {
  311. $c = $s[$i];
  312. if ($c == "\n") {
  313. $i++;
  314. $sep = -1;
  315. $j = $i;
  316. $l = 0;
  317. $nl++;
  318. continue;
  319. }
  320. if ($c == ' ') {
  321. $sep = $i;
  322. }
  323. $l += isset($cw[ord($c)])?$cw[ord($c)]:0 ;
  324. if ($l > $wmax) {
  325. if ($sep == -1) {
  326. if ($i == $j) {
  327. $i++;
  328. }
  329. } else {
  330. $i = $sep + 1;
  331. }
  332. $sep = -1;
  333. $j = $i;
  334. $l = 0;
  335. $nl++;
  336. } else {
  337. $i++;
  338. }
  339. }
  340. return $nl;
  341. }
  342. }
  343. /**
  344. * Table preferences/statistics
  345. *
  346. * This class preserves the table co-ordinates,fields
  347. * and helps in drawing/generating the Tables in PDF document.
  348. *
  349. * @name Table_Stats
  350. * @package PhpMyAdmin
  351. * @see PMA_Schema_PDF
  352. */
  353. class Table_Stats
  354. {
  355. /**
  356. * Defines properties
  357. */
  358. private $_tableName;
  359. private $_showInfo = false;
  360. public $nb_fiels;
  361. public $width = 0;
  362. public $height;
  363. public $fields = array();
  364. public $heightCell = 6;
  365. public $x, $y;
  366. public $primary = array();
  367. private $_ff = PMA_PDF_FONT;
  368. /**
  369. * The "Table_Stats" constructor
  370. *
  371. * @param string $tableName The table name
  372. * @param integer $fontSize The font size
  373. * @param integer $pageNumber The current page number (from the
  374. * $cfg['Servers'][$i]['table_coords'] table)
  375. * @param integer &$sameWideWidth The max. with among tables
  376. * @param boolean $showKeys Whether to display keys or not
  377. * @param boolean $showInfo Whether to display table position or not
  378. *
  379. * @global object The current PDF document
  380. * @global array The relations settings
  381. * @global string The current db name
  382. *
  383. * @return void
  384. *
  385. * @see PMA_Schema_PDF, Table_Stats::Table_Stats_setWidth,
  386. * Table_Stats::Table_Stats_setHeight
  387. */
  388. function __construct($tableName, $fontSize, $pageNumber, &$sameWideWidth,
  389. $showKeys = false, $showInfo = false
  390. ) {
  391. global $pdf, $cfgRelation, $db;
  392. $this->_tableName = $tableName;
  393. $sql = 'DESCRIBE ' . PMA_Util::backquote($tableName);
  394. $result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE);
  395. if (! $result || ! PMA_DBI_num_rows($result)) {
  396. $pdf->Error(sprintf(__('The %s table doesn\'t exist!'), $tableName));
  397. }
  398. // load fields
  399. //check to see if it will load all fields or only the foreign keys
  400. if ($showKeys) {
  401. $indexes = PMA_Index::getFromTable($this->_tableName, $db);
  402. $all_columns = array();
  403. foreach ($indexes as $index) {
  404. $all_columns = array_merge(
  405. $all_columns,
  406. array_flip(array_keys($index->getColumns()))
  407. );
  408. }
  409. $this->fields = array_keys($all_columns);
  410. } else {
  411. while ($row = PMA_DBI_fetch_row($result)) {
  412. $this->fields[] = $row[0];
  413. }
  414. }
  415. $this->_showInfo = $showInfo;
  416. $this->_setHeight();
  417. /*
  418. * setWidth must me after setHeight, because title
  419. * can include table height which changes table width
  420. */
  421. $this->_setWidth($fontSize);
  422. if ($sameWideWidth < $this->width) {
  423. $sameWideWidth = $this->width;
  424. }
  425. $sql = 'SELECT x, y FROM '
  426. . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
  427. . PMA_Util::backquote($cfgRelation['table_coords'])
  428. . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
  429. . ' AND table_name = \'' . PMA_Util::sqlAddSlashes($tableName) . '\''
  430. . ' AND pdf_page_number = ' . $pageNumber;
  431. $result = PMA_queryAsControlUser($sql, false, PMA_DBI_QUERY_STORE);
  432. if (! $result || ! PMA_DBI_num_rows($result)) {
  433. $pdf->Error(
  434. sprintf(
  435. __('Please configure the coordinates for table %s'),
  436. $tableName
  437. )
  438. );
  439. }
  440. list($this->x, $this->y) = PMA_DBI_fetch_row($result);
  441. $this->x = (double) $this->x;
  442. $this->y = (double) $this->y;
  443. /*
  444. * displayfield
  445. */
  446. $this->displayfield = PMA_getDisplayField($db, $tableName);
  447. /*
  448. * index
  449. */
  450. $result = PMA_DBI_query(
  451. 'SHOW INDEX FROM ' . PMA_Util::backquote($tableName) . ';',
  452. null, PMA_DBI_QUERY_STORE
  453. );
  454. if (PMA_DBI_num_rows($result) > 0) {
  455. while ($row = PMA_DBI_fetch_assoc($result)) {
  456. if ($row['Key_name'] == 'PRIMARY') {
  457. $this->primary[] = $row['Column_name'];
  458. }
  459. }
  460. }
  461. }
  462. /**
  463. * Returns title of the current table,
  464. * title can have the dimensions of the table
  465. *
  466. * @return string
  467. */
  468. private function _getTitle()
  469. {
  470. $ret = '';
  471. if ($this->_showInfo) {
  472. $ret = sprintf('%.0fx%0.f', $this->width, $this->height);
  473. }
  474. return $ret . ' ' . $this->_tableName;
  475. }
  476. /**
  477. * Sets the width of the table
  478. *
  479. * @param integer $fontSize The font size
  480. *
  481. * @global object The current PDF document
  482. *
  483. * @access private
  484. *
  485. * @return void
  486. *
  487. * @see PMA_Schema_PDF
  488. */
  489. private function _setWidth($fontSize)
  490. {
  491. global $pdf;
  492. foreach ($this->fields as $field) {
  493. $this->width = max($this->width, $pdf->GetStringWidth($field));
  494. }
  495. $this->width += $pdf->GetStringWidth(' ');
  496. $pdf->SetFont($this->_ff, 'B', $fontSize);
  497. /*
  498. * it is unknown what value must be added, because
  499. * table title is affected by the tabe width value
  500. */
  501. while ($this->width < $pdf->GetStringWidth($this->_getTitle())) {
  502. $this->width += 5;
  503. }
  504. $pdf->SetFont($this->_ff, '', $fontSize);
  505. }
  506. /**
  507. * Sets the height of the table
  508. *
  509. * @return void
  510. *
  511. * @access private
  512. */
  513. private function _setHeight()
  514. {
  515. $this->height = (count($this->fields) + 1) * $this->heightCell;
  516. }
  517. /**
  518. * Do draw the table
  519. *
  520. * @param integer $fontSize The font size
  521. * @param boolean $withDoc Whether to include links to documentation
  522. * @param boolean $setColor Whether to display color
  523. *
  524. * @global object The current PDF document
  525. *
  526. * @access public
  527. *
  528. * @return void
  529. *
  530. * @see PMA_Schema_PDF
  531. */
  532. public function tableDraw($fontSize, $withDoc, $setColor = 0)
  533. {
  534. global $pdf, $withDoc;
  535. $pdf->setXyScale($this->x, $this->y);
  536. $pdf->SetFont($this->_ff, 'B', $fontSize);
  537. if ($setColor) {
  538. $pdf->SetTextColor(200);
  539. $pdf->SetFillColor(0, 0, 128);
  540. }
  541. if ($withDoc) {
  542. $pdf->SetLink($pdf->PMA_links['RT'][$this->_tableName]['-'], -1);
  543. } else {
  544. $pdf->PMA_links['doc'][$this->_tableName]['-'] = '';
  545. }
  546. $pdf->cellScale(
  547. $this->width,
  548. $this->heightCell,
  549. $this->_getTitle(),
  550. 1,
  551. 1,
  552. 'C',
  553. $setColor,
  554. $pdf->PMA_links['doc'][$this->_tableName]['-']
  555. );
  556. $pdf->setXScale($this->x);
  557. $pdf->SetFont($this->_ff, '', $fontSize);
  558. $pdf->SetTextColor(0);
  559. $pdf->SetFillColor(255);
  560. foreach ($this->fields as $field) {
  561. if ($setColor) {
  562. if (in_array($field, $this->primary)) {
  563. $pdf->SetFillColor(215, 121, 123);
  564. }
  565. if ($field == $this->displayfield) {
  566. $pdf->SetFillColor(142, 159, 224);
  567. }
  568. }
  569. if ($withDoc) {
  570. $pdf->SetLink($pdf->PMA_links['RT'][$this->_tableName][$field], -1);
  571. } else {
  572. $pdf->PMA_links['doc'][$this->_tableName][$field] = '';
  573. }
  574. $pdf->cellScale(
  575. $this->width,
  576. $this->heightCell,
  577. ' ' . $field,
  578. 1,
  579. 1,
  580. 'L',
  581. $setColor,
  582. $pdf->PMA_links['doc'][$this->_tableName][$field]
  583. );
  584. $pdf->setXScale($this->x);
  585. $pdf->SetFillColor(255);
  586. }
  587. }
  588. }
  589. /**
  590. * Relation preferences/statistics
  591. *
  592. * This class fetches the table master and foreign fields positions
  593. * and helps in generating the Table references and then connects
  594. * master table's master field to foreign table's foreign key
  595. * in PDF document.
  596. *
  597. * @name Relation_Stats
  598. * @package PhpMyAdmin
  599. * @see PMA_Schema_PDF::SetDrawColor, PMA_Schema_PDF::setLineWidthScale,
  600. * PMA_Schema_PDF::lineScale
  601. */
  602. class Relation_Stats
  603. {
  604. /**
  605. * Defines properties
  606. */
  607. public $xSrc, $ySrc;
  608. public $srcDir;
  609. public $destDir;
  610. public $xDest, $yDest;
  611. public $wTick = 5;
  612. /**
  613. * The "Relation_Stats" constructor
  614. *
  615. * @param string $master_table The master table name
  616. * @param string $master_field The relation field in the master table
  617. * @param string $foreign_table The foreign table name
  618. * @param string $foreign_field The relation field in the foreign table
  619. *
  620. * @return void
  621. *
  622. * @see Relation_Stats::_getXy
  623. */
  624. function __construct($master_table, $master_field, $foreign_table,
  625. $foreign_field
  626. ) {
  627. $src_pos = $this->_getXy($master_table, $master_field);
  628. $dest_pos = $this->_getXy($foreign_table, $foreign_field);
  629. /*
  630. * [0] is x-left
  631. * [1] is x-right
  632. * [2] is y
  633. */
  634. $src_left = $src_pos[0] - $this->wTick;
  635. $src_right = $src_pos[1] + $this->wTick;
  636. $dest_left = $dest_pos[0] - $this->wTick;
  637. $dest_right = $dest_pos[1] + $this->wTick;
  638. $d1 = abs($src_left - $dest_left);
  639. $d2 = abs($src_right - $dest_left);
  640. $d3 = abs($src_left - $dest_right);
  641. $d4 = abs($src_right - $dest_right);
  642. $d = min($d1, $d2, $d3, $d4);
  643. if ($d == $d1) {
  644. $this->xSrc = $src_pos[0];
  645. $this->srcDir = -1;
  646. $this->xDest = $dest_pos[0];
  647. $this->destDir = -1;
  648. } elseif ($d == $d2) {
  649. $this->xSrc = $src_pos[1];
  650. $this->srcDir = 1;
  651. $this->xDest = $dest_pos[0];
  652. $this->destDir = -1;
  653. } elseif ($d == $d3) {
  654. $this->xSrc = $src_pos[0];
  655. $this->srcDir = -1;
  656. $this->xDest = $dest_pos[1];
  657. $this->destDir = 1;
  658. } else {
  659. $this->xSrc = $src_pos[1];
  660. $this->srcDir = 1;
  661. $this->xDest = $dest_pos[1];
  662. $this->destDir = 1;
  663. }
  664. $this->ySrc = $src_pos[2];
  665. $this->yDest = $dest_pos[2];
  666. }
  667. /**
  668. * Gets arrows coordinates
  669. *
  670. * @param string $table The current table name
  671. * @param string $column The relation column name
  672. *
  673. * @return array Arrows coordinates
  674. *
  675. * @access private
  676. */
  677. private function _getXy($table, $column)
  678. {
  679. $pos = array_search($column, $table->fields);
  680. // x_left, x_right, y
  681. return array(
  682. $table->x,
  683. $table->x + $table->width,
  684. $table->y + ($pos + 1.5) * $table->heightCell
  685. );
  686. }
  687. /**
  688. * draws relation links and arrows shows foreign key relations
  689. *
  690. * @param boolean $changeColor Whether to use one color per relation or not
  691. * @param integer $i The id of the link to draw
  692. *
  693. * @global object The current PDF document
  694. *
  695. * @access public
  696. *
  697. * @return void
  698. *
  699. * @see PMA_Schema_PDF
  700. */
  701. public function relationDraw($changeColor, $i)
  702. {
  703. global $pdf;
  704. if ($changeColor) {
  705. $d = $i % 6;
  706. $j = ($i - $d) / 6;
  707. $j = $j % 4;
  708. $j++;
  709. $case = array(
  710. array(1, 0, 0),
  711. array(0, 1, 0),
  712. array(0, 0, 1),
  713. array(1, 1, 0),
  714. array(1, 0, 1),
  715. array(0, 1, 1)
  716. );
  717. list ($a, $b, $c) = $case[$d];
  718. $e = (1 - ($j - 1) / 6);
  719. $pdf->SetDrawColor($a * 255 * $e, $b * 255 * $e, $c * 255 * $e);
  720. } else {
  721. $pdf->SetDrawColor(0);
  722. }
  723. $pdf->setLineWidthScale(0.2);
  724. $pdf->lineScale(
  725. $this->xSrc,
  726. $this->ySrc,
  727. $this->xSrc + $this->srcDir * $this->wTick,
  728. $this->ySrc
  729. );
  730. $pdf->lineScale(
  731. $this->xDest + $this->destDir * $this->wTick,
  732. $this->yDest,
  733. $this->xDest,
  734. $this->yDest
  735. );
  736. $pdf->setLineWidthScale(0.1);
  737. $pdf->lineScale(
  738. $this->xSrc + $this->srcDir * $this->wTick,
  739. $this->ySrc,
  740. $this->xDest + $this->destDir * $this->wTick,
  741. $this->yDest
  742. );
  743. /*
  744. * Draws arrows ->
  745. */
  746. $root2 = 2 * sqrt(2);
  747. $pdf->lineScale(
  748. $this->xSrc + $this->srcDir * $this->wTick * 0.75,
  749. $this->ySrc,
  750. $this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick,
  751. $this->ySrc + $this->wTick / $root2
  752. );
  753. $pdf->lineScale(
  754. $this->xSrc + $this->srcDir * $this->wTick * 0.75,
  755. $this->ySrc,
  756. $this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick,
  757. $this->ySrc - $this->wTick / $root2
  758. );
  759. $pdf->lineScale(
  760. $this->xDest + $this->destDir * $this->wTick / 2,
  761. $this->yDest,
  762. $this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick,
  763. $this->yDest + $this->wTick / $root2
  764. );
  765. $pdf->lineScale(
  766. $this->xDest + $this->destDir * $this->wTick / 2,
  767. $this->yDest,
  768. $this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick,
  769. $this->yDest - $this->wTick / $root2
  770. );
  771. $pdf->SetDrawColor(0);
  772. }
  773. }
  774. /**
  775. * Pdf Relation Schema Class
  776. *
  777. * Purpose of this class is to generate the PDF Document. PDF is widely
  778. * used format for documenting text,fonts,images and 3d vector graphics.
  779. *
  780. * This class inherits Export_Relation_Schema class has common functionality added
  781. * to this class
  782. *
  783. * @name Pdf_Relation_Schema
  784. * @package PhpMyAdmin
  785. */
  786. class PMA_Pdf_Relation_Schema extends PMA_Export_Relation_Schema
  787. {
  788. /**
  789. * Defines properties
  790. */
  791. private $_tables = array();
  792. private $_ff = PMA_PDF_FONT;
  793. private $_xMax = 0;
  794. private $_yMax = 0;
  795. private $_scale;
  796. private $_xMin = 100000;
  797. private $_yMin = 100000;
  798. private $_topMargin = 10;
  799. private $_bottomMargin = 10;
  800. private $_leftMargin = 10;
  801. private $_rightMargin = 10;
  802. private $_tablewidth;
  803. /**
  804. * The "PMA_Pdf_Relation_Schema" constructor
  805. *
  806. * @global object The current PDF Schema document
  807. * @global string The current db name
  808. * @global array The relations settings
  809. * @access private
  810. * @see PMA_Schema_PDF
  811. */
  812. function __construct()
  813. {
  814. global $pdf, $db;
  815. $this->setPageNumber($_POST['pdf_page_number']);
  816. $this->setShowGrid(isset($_POST['show_grid']));
  817. $this->setShowColor(isset($_POST['show_color']));
  818. $this->setShowKeys(isset($_POST['show_keys']));
  819. $this->setTableDimension(isset($_POST['show_table_dimension']));
  820. $this->setAllTablesSameWidth(isset($_POST['all_tables_same_width']));
  821. $this->setWithDataDictionary($_POST['with_doc']);
  822. $this->setOrientation($_POST['orientation']);
  823. $this->setPaper($_POST['paper']);
  824. $this->setExportType($_POST['export_type']);
  825. // Initializes a new document
  826. $pdf = new PMA_Schema_PDF($this->orientation, 'mm', $this->paper);
  827. $pdf->SetTitle(
  828. sprintf(
  829. __('Schema of the %s database - Page %s'),
  830. $GLOBALS['db'],
  831. $this->pageNumber
  832. )
  833. );
  834. $pdf->setCMargin(0);
  835. $pdf->Open();
  836. $pdf->SetAutoPageBreak('auto');
  837. $alltables = $this->getAllTables($db, $this->pageNumber);
  838. if ($this->withDoc) {
  839. $pdf->SetAutoPageBreak('auto', 15);
  840. $pdf->setCMargin(1);
  841. $this->dataDictionaryDoc($alltables);
  842. $pdf->SetAutoPageBreak('auto');
  843. $pdf->setCMargin(0);
  844. }
  845. $pdf->Addpage();
  846. if ($this->withDoc) {
  847. $pdf->SetLink($pdf->PMA_links['RT']['-'], -1);
  848. $pdf->Bookmark(__('Relational schema'));
  849. $pdf->SetAlias('{00}', $pdf->PageNo());
  850. $this->_topMargin = 28;
  851. $this->_bottomMargin = 28;
  852. }
  853. /* snip */
  854. foreach ($alltables as $table) {
  855. if (! isset($this->_tables[$table])) {
  856. $this->_tables[$table] = new Table_Stats(
  857. $table,
  858. null,
  859. $this->pageNumber,
  860. $this->_tablewidth,
  861. $this->showKeys,
  862. $this->tableDimension
  863. );
  864. }
  865. if ($this->sameWide) {
  866. $this->_tables[$table]->width = $this->_tablewidth;
  867. }
  868. $this->_setMinMax($this->_tables[$table]);
  869. }
  870. // Defines the scale factor
  871. $this->_scale = ceil(
  872. max(
  873. ($this->_xMax - $this->_xMin)
  874. / ($pdf->getPageWidth() - $this->_rightMargin - $this->_leftMargin),
  875. ($this->_yMax - $this->_yMin)
  876. / ($pdf->getPageHeight() - $this->_topMargin - $this->_bottomMargin)
  877. ) * 100
  878. ) / 100;
  879. $pdf->setScale(
  880. $this->_scale,
  881. $this->_xMin,
  882. $this->_yMin,
  883. $this->_leftMargin,
  884. $this->_topMargin
  885. );
  886. // Builds and save the PDF document
  887. $pdf->setLineWidthScale(0.1);
  888. if ($this->showGrid) {
  889. $pdf->SetFontSize(10);
  890. $this->_strokeGrid();
  891. }
  892. $pdf->setFontSizeScale(14);
  893. // previous logic was checking master tables and foreign tables
  894. // but I think that looping on every table of the pdf page as a master
  895. // and finding its foreigns is OK (then we can support innodb)
  896. $seen_a_relation = false;
  897. foreach ($alltables as $one_table) {
  898. $exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
  899. if ($exist_rel) {
  900. $seen_a_relation = true;
  901. foreach ($exist_rel as $master_field => $rel) {
  902. // put the foreign table on the schema only if selected
  903. // by the user
  904. // (do not use array_search() because we would have to
  905. // to do a === false and this is not PHP3 compatible)
  906. if (in_array($rel['foreign_table'], $alltables)) {
  907. $this->_addRelation(
  908. $one_table,
  909. $master_field,
  910. $rel['foreign_table'],
  911. $rel['foreign_field'],
  912. $this->tableDimension
  913. );
  914. }
  915. } // end while
  916. } // end if
  917. } // end while
  918. if ($seen_a_relation) {
  919. $this->_drawRelations($this->showColor);
  920. }
  921. $this->_drawTables($this->showColor);
  922. $this->_showOutput($this->pageNumber);
  923. exit();
  924. }
  925. /**
  926. * Sets X and Y minimum and maximum for a table cell
  927. *
  928. * @param string $table The table name of which sets XY co-ordinates
  929. *
  930. * @return void
  931. *
  932. * @access private
  933. */
  934. private function _setMinMax($table)
  935. {
  936. $this->_xMax = max($this->_xMax, $table->x + $table->width);
  937. $this->_yMax = max($this->_yMax, $table->y + $table->height);
  938. $this->_xMin = min($this->_xMin, $table->x);
  939. $this->_yMin = min($this->_yMin, $table->y);
  940. }
  941. /**
  942. * Defines relation objects
  943. *
  944. * @param string $masterTable The master table name
  945. * @param string $masterField The relation field in the master table
  946. * @param string $foreignTable The foreign table name
  947. * @param string $foreignField The relation field in the foreign table
  948. * @param boolean $showInfo Whether to display table position or not
  949. *
  950. * @access private
  951. *
  952. * @return void
  953. *
  954. * @see _setMinMax
  955. */
  956. private function _addRelation($masterTable, $masterField, $foreignTable,
  957. $foreignField, $showInfo
  958. ) {
  959. if (! isset($this->_tables[$masterTable])) {
  960. $this->_tables[$masterTable] = new Table_Stats(
  961. $masterTable, null, $this->pageNumber,
  962. $this->_tablewidth, false, $showInfo
  963. );
  964. $this->_setMinMax($this->_tables[$masterTable]);
  965. }
  966. if (! isset($this->_tables[$foreignTable])) {
  967. $this->_tables[$foreignTable] = new Table_Stats(
  968. $foreignTable, null, $this->pageNumber,
  969. $this->_tablewidth, false, $showInfo
  970. );
  971. $this->_setMinMax($this->_tables[$foreignTable]);
  972. }
  973. $this->relations[] = new Relation_Stats(
  974. $this->_tables[$masterTable], $masterField,
  975. $this->_tables[$foreignTable], $foreignField
  976. );
  977. }
  978. /**
  979. * Draws the grid
  980. *
  981. * @global object the current PMA_Schema_PDF instance
  982. *
  983. * @access private
  984. *
  985. * @return void
  986. *
  987. * @see PMA_Schema_PDF
  988. */
  989. private function _strokeGrid()
  990. {
  991. global $pdf;
  992. $gridSize = 10;
  993. $labelHeight = 4;
  994. $labelWidth = 5;
  995. if ($this->withDoc) {
  996. $topSpace = 6;
  997. $bottomSpace = 15;
  998. } else {
  999. $topSpace = 0;
  1000. $bottomSpace = 0;
  1001. }
  1002. $pdf->SetMargins(0, 0);
  1003. $pdf->SetDrawColor(200, 200, 200);
  1004. // Draws horizontal lines
  1005. for ($l = 0; $l <= intval(($pdf->getPageHeight() - $topSpace - $bottomSpace) / $gridSize); $l++) {
  1006. $pdf->line(
  1007. 0, $l * $gridSize + $topSpace,
  1008. $pdf->getPageWidth(), $l * $gridSize + $topSpace
  1009. );
  1010. // Avoid duplicates
  1011. if ($l > 0
  1012. && $l <= intval(($pdf->getPageHeight() - $topSpace - $bottomSpace - $labelHeight) / $gridSize)
  1013. ) {
  1014. $pdf->SetXY(0, $l * $gridSize + $topSpace);
  1015. $label = (string) sprintf(
  1016. '%.0f',
  1017. ($l * $gridSize + $topSpace - $this->_topMargin)
  1018. * $this->_scale + $this->_yMin
  1019. );
  1020. $pdf->Cell($labelWidth, $labelHeight, ' ' . $label);
  1021. } // end if
  1022. } // end for
  1023. // Draws vertical lines
  1024. for ($j = 0; $j <= intval($pdf->getPageWidth() / $gridSize); $j++) {
  1025. $pdf->line(
  1026. $j * $gridSize,
  1027. $topSpace,
  1028. $j * $gridSize,
  1029. $pdf->getPageHeight() - $bottomSpace
  1030. );
  1031. $pdf->SetXY($j * $gridSize, $topSpace);
  1032. $label = (string) sprintf(
  1033. '%.0f',
  1034. ($j * $gridSize - $this->_leftMargin) * $this->_scale + $this->_xMin
  1035. );
  1036. $pdf->Cell($labelWidth, $labelHeight, $label);
  1037. }
  1038. }
  1039. /**
  1040. * Draws relation arrows
  1041. *
  1042. * @param boolean $changeColor Whether to use one color per relation or not
  1043. *
  1044. * @access private
  1045. *
  1046. * @return void
  1047. *
  1048. * @see Relation_Stats::relationdraw()
  1049. */
  1050. private function _drawRelations($changeColor)
  1051. {
  1052. $i = 0;
  1053. foreach ($this->relations as $relation) {
  1054. $relation->relationDraw($changeColor, $i);
  1055. $i++;
  1056. }
  1057. }
  1058. /**
  1059. * Draws tables
  1060. *
  1061. * @param boolean $changeColor Whether to display table position or not
  1062. *
  1063. * @access private
  1064. *
  1065. * @return void
  1066. *
  1067. * @see Table_Stats::tableDraw()
  1068. */
  1069. private function _drawTables($changeColor = 0)
  1070. {
  1071. foreach ($this->_tables as $table) {
  1072. $table->tableDraw(null, $this->withDoc, $changeColor);
  1073. }
  1074. }
  1075. /**
  1076. * Ouputs the PDF document to a file
  1077. * or sends the output to browser
  1078. *
  1079. * @param integer $pageNumber page number
  1080. *
  1081. * @global object The current PDF document
  1082. * @global string The current database name
  1083. * @global integer The current page number (from the
  1084. * $cfg['Servers'][$i]['table_coords'] table)
  1085. * @access private
  1086. *
  1087. * @return void
  1088. *
  1089. * @see PMA_Schema_PDF
  1090. */
  1091. private function _showOutput($pageNumber)
  1092. {
  1093. global $pdf, $cfgRelation;
  1094. // Get the name of this pdfpage to use as filename
  1095. $_name_sql = 'SELECT page_descr FROM '
  1096. . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
  1097. . PMA_Util::backquote($cfgRelation['pdf_pages'])
  1098. . ' WHERE page_nr = ' . $pageNumber;
  1099. $_name_rs = PMA_queryAsControlUser($_name_sql);
  1100. if ($_name_rs) {
  1101. $_name_row = PMA_DBI_fetch_row($_name_rs);
  1102. $filename = $_name_row[0] . '.pdf';
  1103. }
  1104. if (empty($filename)) {
  1105. $filename = $pageNumber . '.pdf';
  1106. }
  1107. $pdf->Download($filename);
  1108. }
  1109. /**
  1110. * Generates data dictionary pages.
  1111. *
  1112. * @param bool $alltables Tables to document.
  1113. *
  1114. * @return void
  1115. */
  1116. public function dataDictionaryDoc($alltables)
  1117. {
  1118. global $db, $pdf, $orientation, $paper;
  1119. // TOC
  1120. $pdf->addpage($_POST['orientation']);
  1121. $pdf->Cell(0, 9, __('Table of contents'), 1, 0, 'C');
  1122. $pdf->Ln(15);
  1123. $i = 1;
  1124. foreach ($alltables as $table) {
  1125. $pdf->PMA_links['doc'][$table]['-'] = $pdf->AddLink();
  1126. $pdf->SetX(10);
  1127. // $pdf->Ln(1);
  1128. $pdf->Cell(
  1129. 0, 6, __('Page number:') . ' {' . sprintf("%02d", $i) . '}', 0, 0,
  1130. 'R', 0, $pdf->PMA_links['doc'][$table]['-']
  1131. );
  1132. $pdf->SetX(10);
  1133. $pdf->Cell(
  1134. 0, 6, $i . ' ' . $table, 0, 1,
  1135. 'L', 0, $pdf->PMA_links['doc'][$table]['-']
  1136. );
  1137. // $pdf->Ln(1);
  1138. $fields = PMA_DBI_get_columns($GLOBALS['db'], $table);
  1139. foreach ($fields as $row) {
  1140. $pdf->SetX(20);
  1141. $field_name = $row['Field'];
  1142. $pdf->PMA_links['doc'][$table][$field_name] = $pdf->AddLink();
  1143. //$pdf->Cell(
  1144. // 0, 6, $field_name, 0, 1,
  1145. // 'L', 0, $pdf->PMA_links['doc'][$table][$field_name]
  1146. //);
  1147. }
  1148. $i++;
  1149. }
  1150. $pdf->PMA_links['RT']['-'] = $pdf->AddLink();
  1151. $pdf->SetX(10);
  1152. $pdf->Cell(
  1153. 0, 6, __('Page number:') . ' {00}', 0, 0,
  1154. 'R', 0, $pdf->PMA_links['RT']['-']
  1155. );
  1156. $pdf->SetX(10);
  1157. $pdf->Cell(
  1158. 0, 6, $i . ' ' . __('Relational schema'), 0, 1,
  1159. 'L', 0, $pdf->PMA_links['RT']['-']
  1160. );
  1161. $z = 0;
  1162. foreach ($alltables as $table) {
  1163. $z++;
  1164. $pdf->SetAutoPageBreak(true, 15);
  1165. $pdf->addpage($_POST['orientation']);
  1166. $pdf->Bookmark($table);
  1167. $pdf->SetAlias('{' . sprintf("%02d", $z) . '}', $pdf->PageNo());
  1168. $pdf->PMA_links['RT'][$table]['-'] = $pdf->AddLink();
  1169. $pdf->SetLink($pdf->PMA_links['doc'][$table]['-'], -1);
  1170. $pdf->SetFont($this->_ff, 'B', 18);
  1171. $pdf->Cell(
  1172. 0, 8, $z . ' ' . $table, 1, 1,
  1173. 'C', 0, $pdf->PMA_links['RT'][$table]['-']
  1174. );
  1175. $pdf->SetFont($this->_ff, '', 8);
  1176. $pdf->ln();
  1177. $cfgRelation = PMA_getRelationsParam();
  1178. $comments = PMA_getComments($db, $table);
  1179. if ($cfgRelation['mimework']) {
  1180. $mime_map = PMA_getMIME($db, $table, true);
  1181. }
  1182. /**
  1183. * Gets table informations
  1184. */
  1185. $showtable = PMA_Table::sGetStatusInfo($db, $table);
  1186. $show_comment = isset($showtable['Comment'])
  1187. ? $showtable['Comment']
  1188. : '';
  1189. $create_time = isset($showtable['Create_time'])
  1190. ? PMA_Util::localisedDate(
  1191. strtotime($showtable['Create_time'])
  1192. )
  1193. : '';
  1194. $update_time = isset($showtable['Update_time'])
  1195. ? PMA_Util::localisedDate(
  1196. strtotime($showtable['Update_time'])
  1197. )
  1198. : '';
  1199. $check_time = isset($showtable['Check_time'])
  1200. ? PMA_Util::localisedDate(
  1201. strtotime($showtable['Check_time'])
  1202. )
  1203. : '';
  1204. /**
  1205. * Gets table keys and retains them
  1206. */
  1207. $result = PMA_DBI_query(
  1208. 'SHOW KEYS FROM ' . PMA_Util::backquote($table) . ';'
  1209. );
  1210. $primary = '';
  1211. $indexes = array();
  1212. $lastIndex = '';
  1213. $indexes_info = array();
  1214. $indexes_data = array();
  1215. $pk_array = array(); // will be use to emphasis prim. keys in the table
  1216. // view
  1217. while ($row = PMA_DBI_fetch_assoc($result)) {
  1218. // Backups the list of primary keys
  1219. if ($row['Key_name'] == 'PRIMARY') {
  1220. $primary .= $row['Column_name'] . ', ';
  1221. $pk_array[$row['Column_name']] = 1;
  1222. }
  1223. // Retains keys informations
  1224. if ($row['Key_name'] != $lastIndex) {
  1225. $indexes[] = $row['Key_name'];
  1226. $lastIndex = $row['Key_name'];
  1227. }
  1228. $indexes_info[$row['Key_name']]['Sequences'][]
  1229. = $row['Seq_in_index'];
  1230. $indexes_info[$row['Key_name']]['Non_unique'] = $row['Non_unique'];
  1231. if (isset($row['Cardinality'])) {
  1232. $indexes_info[$row['Key_name']]['Cardinality']
  1233. = $row['Cardinality'];
  1234. }
  1235. // I don't know what does following column mean....
  1236. // $indexes_info[$row['Key_name']]['Packed'] = $row['Packed'];
  1237. $indexes_info[$row['Key_name']]['Comment'] = $row['Comment'];
  1238. $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Column_name']
  1239. = $row['Column_name'];
  1240. if (isset($row['Sub_part'])) {
  1241. $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Sub_part']
  1242. = $row['Sub_part'];
  1243. }
  1244. } // end while
  1245. if ($result) {
  1246. PMA_DBI_free_result($result);
  1247. }
  1248. /**
  1249. * Gets fields properties
  1250. */
  1251. $columns = PMA_DBI_get_columns($db, $table);
  1252. // Check if we can use Relations
  1253. if (!empty($cfgRelation['relation'])) {
  1254. // Find which tables are related with the current one and write it in
  1255. // an array
  1256. $res_rel = PMA_getForeigners($db, $table);
  1257. if (count($res_rel) > 0) {
  1258. $have_rel = true;
  1259. } else {
  1260. $have_rel = false;
  1261. }
  1262. } else {
  1263. $have_rel = false;
  1264. } // end if
  1265. /**
  1266. * Displays the comments of the table if MySQL >= 3.23
  1267. */
  1268. $break = false;
  1269. if (! empty($show_comment)) {
  1270. $pdf->Cell(0, 3, __('Table comments') . ' : ' . $show_comment, 0, 1);
  1271. $break = true;
  1272. }
  1273. if (! empty($create_time)) {
  1274. $pdf->Cell(0, 3, __('Creation') . ': ' . $create_time, 0, 1);
  1275. $break = true;
  1276. }
  1277. if (! empty($update_time)) {
  1278. $pdf->Cell(0, 3, __('Last update') . ': ' . $update_time, 0, 1);
  1279. $break = true;
  1280. }
  1281. if (! empty($check_time)) {
  1282. $pdf->Cell(0, 3, __('Last check') . ': ' . $check_time, 0, 1);
  1283. $break = true;
  1284. }
  1285. if ($break == true) {
  1286. $pdf->Cell(0, 3, '', 0, 1);
  1287. $pdf->Ln();
  1288. }
  1289. $pdf->SetFont($this->_ff, 'B');
  1290. if (isset($orientation) && $orientation == 'L') {
  1291. $pdf->Cell(25, 8, __('Column'), 1, 0, 'C');
  1292. $pdf->Cell(20, 8, __('Type'), 1, 0, 'C');
  1293. $pdf->Cell(20, 8, __('Attributes'), 1, 0, 'C');
  1294. $pdf->Cell(10, 8, __('Null'), 1, 0, 'C');
  1295. $pdf->Cell(20, 8, __('Default'), 1, 0, 'C');
  1296. $pdf->Cell(25, 8, __('Extra'), 1, 0, 'C');
  1297. $pdf->Cell(45, 8, __('Links to'), 1, 0, 'C');
  1298. if ($paper == 'A4') {
  1299. $comments_width = 67;
  1300. } else {
  1301. // this is really intended for 'letter'
  1302. /**
  1303. * @todo find optimal width for all formats
  1304. */
  1305. $comments_width = 50;
  1306. }
  1307. $pdf->Cell($comments_width, 8, __('Comments'), 1, 0, 'C');
  1308. $pdf->Cell(45, 8, 'MIME', 1, 1, 'C');
  1309. $pdf->SetWidths(
  1310. array(25, 20, 20, 10, 20, 25, 45, $comments_width, 45)
  1311. );
  1312. } else {
  1313. $pdf->Cell(20, 8, __('Column'), 1, 0, 'C');
  1314. $pdf->Cell(20, 8, __('Type'), 1, 0, 'C');
  1315. $pdf->Cell(20, 8, __('Attributes'), 1, 0, 'C');
  1316. $pdf->Cell(10, 8, __('Null'), 1, 0, 'C');
  1317. $pdf->Cell(15, 8, __('Default'), 1, 0, 'C');
  1318. $pdf->Cell(15, 8, __('Extra'), 1, 0, 'C');
  1319. $pdf->Cell(30, 8, __('Links to'), 1, 0, 'C');
  1320. $pdf->Cell(30, 8, __('Comments'), 1, 0, 'C');
  1321. $pdf->Cell(30, 8, 'MIME', 1, 1, 'C');
  1322. $pdf->SetWidths(array(20, 20, 20, 10, 15, 15, 30, 30, 30));
  1323. }
  1324. $pdf->SetFont($this->_ff, '');
  1325. foreach ($columns as $row) {
  1326. $extracted_columnspec
  1327. = PMA_Util::extractColumnSpec($row['Type']);
  1328. $type = $extracted_columnspec['print_type'];
  1329. $attribute = $extracted_columnspec['attribute'];
  1330. if (! isset($row['Default'])) {
  1331. if ($row['Null'] != '' && $row['Null'] != 'NO') {
  1332. $row['Default'] = 'NULL';
  1333. }
  1334. }
  1335. $field_name = $row['Field'];
  1336. // $pdf->Ln();
  1337. $pdf->PMA_links['RT'][$table][$field_name] = $pdf->AddLink();
  1338. $pdf->Bookmark($field_name, 1, -1);
  1339. $pdf->SetLink($pdf->PMA_links['doc'][$table][$field_name], -1);
  1340. $pdf_row = array(
  1341. $field_name,
  1342. $type,
  1343. $attribute,
  1344. ($row['Null'] == '' || $row['Null'] == 'NO')
  1345. ? __('No')
  1346. : __('Yes'),
  1347. (isset($row['Default']) ? $row['Default'] : ''),
  1348. $row['Extra'],
  1349. (isset($res_rel[$field_name])
  1350. ? $res_rel[$field_name]['foreign_table'] . ' -> ' . $res_rel[$field_name]['foreign_field']
  1351. : ''),
  1352. (isset($comments[$field_name])
  1353. ? $comments[$field_name]
  1354. : ''),
  1355. (isset($mime_map) && isset($mime_map[$field_name])
  1356. ? str_replace('_', '/', $mime_map[$field_name]['mimetype'])
  1357. : '')
  1358. );
  1359. $links[0] = $pdf->PMA_links['RT'][$table][$field_name];
  1360. if (isset($res_rel[$field_name]['foreign_table'])
  1361. && isset($res_rel[$field_name]['foreign_field'])
  1362. && isset($pdf->PMA_links['doc'][$res_rel[$field_name]['foreign_table']][$res_rel[$field_name]['foreign_field']])
  1363. ) {
  1364. $links[6] = $pdf->PMA_links['doc'][$res_rel[$field_name]['foreign_table']][$res_rel[$field_name]['foreign_field']];
  1365. } else {
  1366. unset($links[6]);
  1367. }
  1368. $pdf->Row($pdf_row, $links);
  1369. } // end foreach
  1370. $pdf->SetFont($this->_ff, '', 14);
  1371. } //end each
  1372. }
  1373. }
  1374. ?>