Pdf.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * PDF schema handling
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. namespace PhpMyAdmin\Plugins\Schema\Pdf;
  9. use PhpMyAdmin\Pdf as PdfLib;
  10. use PhpMyAdmin\Relation;
  11. use PhpMyAdmin\Util;
  12. /**
  13. * Skip the plugin if TCPDF is not available.
  14. */
  15. if (! class_exists('TCPDF')) {
  16. $GLOBALS['skip_import'] = true;
  17. return;
  18. }
  19. /**
  20. * block attempts to directly run this script
  21. */
  22. if (getcwd() == dirname(__FILE__)) {
  23. die('Attack stopped');
  24. }
  25. /**
  26. * Extends the "TCPDF" class and helps
  27. * in developing the structure of PDF Schema Export
  28. *
  29. * @access public
  30. * @package PhpMyAdmin
  31. * @see TCPDF
  32. */
  33. class Pdf extends PdfLib
  34. {
  35. /**
  36. * Defines properties
  37. */
  38. var $_xMin;
  39. var $_yMin;
  40. var $leftMargin = 10;
  41. var $topMargin = 10;
  42. var $scale;
  43. var $PMA_links;
  44. var $Outlines = array();
  45. var $def_outlines;
  46. var $widths;
  47. private $_ff = PdfLib::PMA_PDF_FONT;
  48. private $_offline;
  49. private $_pageNumber;
  50. private $_withDoc;
  51. private $_db;
  52. /**
  53. * @var Relation $relation
  54. */
  55. private $relation;
  56. /**
  57. * Constructs PDF for schema export.
  58. *
  59. * @param string $orientation page orientation
  60. * @param string $unit unit
  61. * @param string $paper the format used for pages
  62. * @param int $pageNumber schema page number that is being exported
  63. * @param boolean $withDoc with document dictionary
  64. * @param string $db the database name
  65. *
  66. * @access public
  67. */
  68. public function __construct(
  69. $orientation, $unit, $paper, $pageNumber, $withDoc, $db
  70. ) {
  71. parent::__construct($orientation, $unit, $paper);
  72. $this->_pageNumber = $pageNumber;
  73. $this->_withDoc = $withDoc;
  74. $this->_db = $db;
  75. $this->relation = new Relation();
  76. }
  77. /**
  78. * Sets the value for margins
  79. *
  80. * @param float $c_margin margin
  81. *
  82. * @return void
  83. */
  84. public function setCMargin($c_margin)
  85. {
  86. $this->cMargin = $c_margin;
  87. }
  88. /**
  89. * Sets the scaling factor, defines minimum coordinates and margins
  90. *
  91. * @param float|int $scale The scaling factor
  92. * @param float|int $xMin The minimum X coordinate
  93. * @param float|int $yMin The minimum Y coordinate
  94. * @param float|int $leftMargin The left margin
  95. * @param float|int $topMargin The top margin
  96. *
  97. * @return void
  98. */
  99. public function setScale($scale = 1, $xMin = 0, $yMin = 0,
  100. $leftMargin = -1, $topMargin = -1
  101. ) {
  102. $this->scale = $scale;
  103. $this->_xMin = $xMin;
  104. $this->_yMin = $yMin;
  105. if ($this->leftMargin != -1) {
  106. $this->leftMargin = $leftMargin;
  107. }
  108. if ($this->topMargin != -1) {
  109. $this->topMargin = $topMargin;
  110. }
  111. }
  112. /**
  113. * Outputs a scaled cell
  114. *
  115. * @param float|int $w The cell width
  116. * @param float|int $h The cell height
  117. * @param string $txt The text to output
  118. * @param mixed $border Whether to add borders or not
  119. * @param integer $ln Where to put the cursor once the output is done
  120. * @param string $align Align mode
  121. * @param integer $fill Whether to fill the cell with a color or not
  122. * @param string $link Link
  123. *
  124. * @return void
  125. *
  126. * @see TCPDF::Cell()
  127. */
  128. public function cellScale($w, $h = 0, $txt = '', $border = 0, $ln = 0,
  129. $align = '', $fill = 0, $link = ''
  130. ) {
  131. $h = $h / $this->scale;
  132. $w = $w / $this->scale;
  133. $this->Cell($w, $h, $txt, $border, $ln, $align, $fill, $link);
  134. }
  135. /**
  136. * Draws a scaled line
  137. *
  138. * @param float $x1 The horizontal position of the starting point
  139. * @param float $y1 The vertical position of the starting point
  140. * @param float $x2 The horizontal position of the ending point
  141. * @param float $y2 The vertical position of the ending point
  142. *
  143. * @return void
  144. *
  145. * @see TCPDF::Line()
  146. */
  147. public function lineScale($x1, $y1, $x2, $y2)
  148. {
  149. $x1 = ($x1 - $this->_xMin) / $this->scale + $this->leftMargin;
  150. $y1 = ($y1 - $this->_yMin) / $this->scale + $this->topMargin;
  151. $x2 = ($x2 - $this->_xMin) / $this->scale + $this->leftMargin;
  152. $y2 = ($y2 - $this->_yMin) / $this->scale + $this->topMargin;
  153. $this->Line($x1, $y1, $x2, $y2);
  154. }
  155. /**
  156. * Sets x and y scaled positions
  157. *
  158. * @param float $x The x position
  159. * @param float $y The y position
  160. *
  161. * @return void
  162. *
  163. * @see TCPDF::SetXY()
  164. */
  165. public function setXyScale($x, $y)
  166. {
  167. $x = ($x - $this->_xMin) / $this->scale + $this->leftMargin;
  168. $y = ($y - $this->_yMin) / $this->scale + $this->topMargin;
  169. $this->SetXY($x, $y);
  170. }
  171. /**
  172. * Sets the X scaled positions
  173. *
  174. * @param float $x The x position
  175. *
  176. * @return void
  177. *
  178. * @see TCPDF::SetX()
  179. */
  180. public function setXScale($x)
  181. {
  182. $x = ($x - $this->_xMin) / $this->scale + $this->leftMargin;
  183. $this->SetX($x);
  184. }
  185. /**
  186. * Sets the scaled font size
  187. *
  188. * @param float $size The font size (in points)
  189. *
  190. * @return void
  191. *
  192. * @see TCPDF::SetFontSize()
  193. */
  194. public function setFontSizeScale($size)
  195. {
  196. // Set font size in points
  197. $size = $size / $this->scale;
  198. $this->SetFontSize($size);
  199. }
  200. /**
  201. * Sets the scaled line width
  202. *
  203. * @param float $width The line width
  204. *
  205. * @return void
  206. *
  207. * @see TCPDF::SetLineWidth()
  208. */
  209. public function setLineWidthScale($width)
  210. {
  211. $width = $width / $this->scale;
  212. $this->SetLineWidth($width);
  213. }
  214. /**
  215. * This method is used to render the page header.
  216. *
  217. * @return void
  218. *
  219. * @see TCPDF::Header()
  220. */
  221. // @codingStandardsIgnoreLine
  222. public function Header()
  223. {
  224. // We only show this if we find something in the new pdf_pages table
  225. // This function must be named "Header" to work with the TCPDF library
  226. if ($this->_withDoc) {
  227. if ($this->_offline || $this->_pageNumber == -1) {
  228. $pg_name = __("PDF export page");
  229. } else {
  230. $test_query = 'SELECT * FROM '
  231. . Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
  232. . Util::backquote($GLOBALS['cfgRelation']['pdf_pages'])
  233. . ' WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($this->_db)
  234. . '\' AND page_nr = \'' . $this->_pageNumber . '\'';
  235. $test_rs = $this->relation->queryAsControlUser($test_query);
  236. $pages = @$GLOBALS['dbi']->fetchAssoc($test_rs);
  237. $pg_name = ucfirst($pages['page_descr']);
  238. }
  239. $this->SetFont($this->_ff, 'B', 14);
  240. $this->Cell(0, 6, $pg_name, 'B', 1, 'C');
  241. $this->SetFont($this->_ff, '');
  242. $this->Ln();
  243. }
  244. }
  245. /**
  246. * This function must be named "Footer" to work with the TCPDF library
  247. *
  248. * @return void
  249. *
  250. * @see PDF::Footer()
  251. */
  252. // @codingStandardsIgnoreLine
  253. public function Footer()
  254. {
  255. if ($this->_withDoc) {
  256. parent::Footer();
  257. }
  258. }
  259. /**
  260. * Sets widths
  261. *
  262. * @param array $w array of widths
  263. *
  264. * @return void
  265. */
  266. public function setWidths(array $w)
  267. {
  268. // column widths
  269. $this->widths = $w;
  270. }
  271. /**
  272. * Generates table row.
  273. *
  274. * @param array $data Data for table
  275. * @param array $links Links for table cells
  276. *
  277. * @return void
  278. */
  279. public function row(array $data, array $links)
  280. {
  281. // line height
  282. $nb = 0;
  283. $data_cnt = count($data);
  284. for ($i = 0;$i < $data_cnt;$i++) {
  285. $nb = max($nb, $this->numLines($this->widths[$i], $data[$i]));
  286. }
  287. $il = $this->FontSize;
  288. $h = ($il + 1) * $nb;
  289. // page break if necessary
  290. $this->CheckPageBreak($h);
  291. // draw the cells
  292. $data_cnt = count($data);
  293. for ($i = 0;$i < $data_cnt;$i++) {
  294. $w = $this->widths[$i];
  295. // save current position
  296. $x = $this->GetX();
  297. $y = $this->GetY();
  298. // draw the border
  299. $this->Rect($x, $y, $w, $h);
  300. if (isset($links[$i])) {
  301. $this->Link($x, $y, $w, $h, $links[$i]);
  302. }
  303. // print text
  304. $this->MultiCell($w, $il + 1, $data[$i], 0, 'L');
  305. // go to right side
  306. $this->SetXY($x + $w, $y);
  307. }
  308. // go to line
  309. $this->Ln($h);
  310. }
  311. /**
  312. * Compute number of lines used by a multicell of width w
  313. *
  314. * @param int $w width
  315. * @param string $txt text
  316. *
  317. * @return int
  318. */
  319. public function numLines($w, $txt)
  320. {
  321. $cw = &$this->CurrentFont['cw'];
  322. if ($w == 0) {
  323. $w = $this->w - $this->rMargin - $this->x;
  324. }
  325. $wmax = ($w-2 * $this->cMargin) * 1000 / $this->FontSize;
  326. $s = str_replace("\r", '', $txt);
  327. $nb = strlen($s);
  328. if ($nb > 0 && $s[$nb-1] == "\n") {
  329. $nb--;
  330. }
  331. $sep = -1;
  332. $i = 0;
  333. $j = 0;
  334. $l = 0;
  335. $nl = 1;
  336. while ($i < $nb) {
  337. $c = $s[$i];
  338. if ($c == "\n") {
  339. $i++;
  340. $sep = -1;
  341. $j = $i;
  342. $l = 0;
  343. $nl++;
  344. continue;
  345. }
  346. if ($c == ' ') {
  347. $sep = $i;
  348. }
  349. $l += isset($cw[mb_ord($c)])?$cw[mb_ord($c)]:0 ;
  350. if ($l > $wmax) {
  351. if ($sep == -1) {
  352. if ($i == $j) {
  353. $i++;
  354. }
  355. } else {
  356. $i = $sep + 1;
  357. }
  358. $sep = -1;
  359. $j = $i;
  360. $l = 0;
  361. $nl++;
  362. } else {
  363. $i++;
  364. }
  365. }
  366. return $nl;
  367. }
  368. /**
  369. * Set whether the document is generated from client side DB
  370. *
  371. * @param string $value whether offline
  372. *
  373. * @return void
  374. *
  375. * @access private
  376. */
  377. public function setOffline($value)
  378. {
  379. $this->_offline = $value;
  380. }
  381. }