Pdf_Relation_Schema.class.php 44 KB

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