PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/pdf/code/trunk/administrator/components/com_artofpdf/models/pdf.php

https://bitbucket.org/eddieajau/the-art-of-joomla-archive
PHP | 490 lines | 230 code | 72 blank | 188 comment | 20 complexity | 0f57d178fbc83998c5228aaf344bd4b2 MD5 | raw file
  1. <?php
  2. /**
  3. * @version $Id: pdf.php 385 2010-11-03 09:01:13Z eddieajau $
  4. * @package NewLifeInIT
  5. * @subpackage com_artofpdf
  6. * @copyright Copyright 2010 New Life in IT Pty Ltd. All rights reserved.
  7. * @license GNU General Public License version 2 or later.
  8. * @link http://www.theartofjoomla.com
  9. */
  10. // No direct access
  11. defined('_JEXEC') or die;
  12. juimport('joomla.application.component.modeladmin');
  13. juimport('joomla.database.databasequery');
  14. /**
  15. * Pdf model.
  16. *
  17. * @package NewLifeInIT
  18. * @subpackage com_artofpdf
  19. * @since 1.0
  20. */
  21. class ArtofPdfModelPdf extends JModelAdmin
  22. {
  23. /**
  24. * Adds the Table of Contents to the PDF document.
  25. *
  26. * @param TCPDF $doc
  27. * @param JObject $params
  28. *
  29. * @return void
  30. * @since 1.0
  31. */
  32. protected static function addPdfToc(TCPDF $doc, JObject $params)
  33. {
  34. // add a new page for TOC
  35. $doc->addTOCPage();
  36. // write the TOC title and/or other elements on the TOC page
  37. //$doc->SetFont('times', 'B', 16);
  38. $doc->SetFont('helvetica', '', 16);
  39. $doc->MultiCell(0, 0, JText::_('COM_ARTOFPDF_PDF_TABLE_OF_CONTENTS'), 0, 'C', 0, 1, '', '', true, 0);
  40. $doc->Ln();
  41. //$doc->SetFont('helvetica', '', 10);
  42. // define styles for various bookmark levels
  43. $bookmark_templates = array();
  44. /*
  45. * The key of the $bookmark_templates array represent the bookmark level (from 0 to n).
  46. * The following templates will be replaced with proper content:
  47. * #TOC_DESCRIPTION# this will be replaced with the bookmark description;
  48. * #TOC_PAGE_NUMBER# this will be replaced with page number.
  49. *
  50. * NOTES:
  51. * If you want to align the page number on the right you have to use a monospaced font like courier, otherwise you can left align using any font type.
  52. * The following is just an example, you can get various styles by combining various HTML elements.
  53. */
  54. // A monospaced font for the page number is mandatory to get the right alignment
  55. $bookmark_templates[0] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td width="165mm"><span style="font-weight:bold;font-size:12pt;color:black;">#TOC_DESCRIPTION#</span></td><td width="15mm"><span style="font-weight:bold;font-size:12pt;color:black;" align="right">#TOC_PAGE_NUMBER#</span></td></tr></table>';
  56. $bookmark_templates[1] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td width="5mm">&nbsp;</td><td width="160mm"><span style="font-size:11pt;color:#6a1a41;">#TOC_DESCRIPTION#</span></td><td width="15mm"><span style="font-weight:bold;font-size:11pt;color:#6a1a41;" align="right">#TOC_PAGE_NUMBER#</span></td></tr></table>';
  57. $bookmark_templates[2] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td width="10mm">&nbsp;</td><td width="155mm"><span style="font-size:10pt;color:#666666;"><i>#TOC_DESCRIPTION#</i></span></td><td width="15mm"><span style="font-weight:bold;font-size:10pt;color:#666666;" align="right">#TOC_PAGE_NUMBER#</span></td></tr></table>';
  58. $bookmark_templates[3] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td width="15mm">&nbsp;</td><td width="150mm"><span style="font-size:10pt;color:#666666;"><i>#TOC_DESCRIPTION#</i></span></td><td width="15mm"><span style="font-weight:bold;font-size:10pt;color:#666666;" align="right">#TOC_PAGE_NUMBER#</span></td></tr></table>';
  59. // add other bookmark level templates here ...
  60. // add table of content at page 1
  61. // (check the example n. 45 for a text-only TOC
  62. $doc->addHTMLTOC($page=1, $toc_name='INDEX', $bookmark_templates, $correct_align=true);
  63. // end of TOC page
  64. $doc->endTOCPage();
  65. }
  66. /**
  67. * Gets the basic PDF document.
  68. *
  69. * @param JObject $params
  70. *
  71. * @return TCPDF
  72. * @since 1.0
  73. */
  74. protected static function &getPdfDocument(JObject $params)
  75. {
  76. // Initialise variables.
  77. $user = JFactory::getUser();
  78. // Initialiase the PDF engine.
  79. self::initPdfEngine();
  80. // Create and prepare the PDF document.
  81. $doc = new TCPDF(
  82. $params->get('page_orientation', 'P'),
  83. $params->get('unit', 'mm'),
  84. $params->get('page_format', 'A4'),
  85. true, // Unicode
  86. 'UTF-8',
  87. $params->get('disk_cache', false)
  88. );
  89. $doc->SetMargins(
  90. $params->get('margin_left', 15),
  91. $params->get('margin_top', 27),
  92. $params->get('margin_right', 15)
  93. );
  94. $doc->SetAutoPageBreak(
  95. true, // Automode on or off
  96. $params->get('margin_bottom', 25)
  97. );
  98. $doc->SetHeaderMargin(
  99. $params->get('margin_header', 5)
  100. );
  101. $doc->SetFooterMargin(
  102. $params->get('margin_footer', 10)
  103. );
  104. $doc->setImageScale(
  105. $params->get('image_scale_ratio', 4)
  106. );
  107. $doc->SetCreator(
  108. $params->get('creator', $user->get('name', 'Joomla!'))
  109. );
  110. // TODO Optionally turn off headers
  111. // $doc->setPrintHeader(false);
  112. // $doc->setPrintFooter(false);
  113. $doc->SetHeaderData(
  114. $params->get('logo'),
  115. $params->get('logo_width', 0),
  116. $params->get('header_title'),
  117. $params->get('header_string')
  118. );
  119. $lang = JFactory::getLanguage();
  120. $doc->setRTL($lang->isRTL());
  121. //$doc->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
  122. $doc->SetFont(
  123. 'helvetica', // Family
  124. '', // Style
  125. 8 // Size
  126. );
  127. $doc->setHeaderFont(
  128. array(
  129. 'helvetica', // Family
  130. '', // Style
  131. 6 // Size
  132. )
  133. );
  134. $doc->setFooterFont(
  135. array(
  136. 'helvetica', // Family
  137. '', // Style
  138. 6 // Size
  139. )
  140. );
  141. return $doc;
  142. }
  143. /**
  144. * Once only initialiasation PDF settings.
  145. *
  146. * @return void
  147. */
  148. protected static function initPdfEngine()
  149. {
  150. static $done;
  151. if ($done) {
  152. return;
  153. }
  154. // Configure manually.
  155. define('K_TCPDF_EXTERNAL_CONFIG', true);
  156. define('K_PATH_MAIN', JPATH_COMPONENT_ADMINISTRATOR.'/libraries/tcpdf');
  157. define('K_PATH_URL', JPATH_BASE);
  158. define('K_PATH_FONTS', K_PATH_MAIN.'/fonts/');
  159. define('K_PATH_CACHE', K_PATH_MAIN.'/cache');
  160. define('K_PATH_URL_CACHE', K_PATH_URL.'/cache');
  161. define('K_PATH_IMAGES', K_PATH_MAIN.'/images');
  162. define('K_BLANK_IMAGE', K_PATH_IMAGES.'/_blank.png');
  163. define('K_CELL_HEIGHT_RATIO', 1.25);
  164. define('K_TITLE_MAGNIFICATION', 1.3);
  165. define('K_SMALL_RATIO', 2/3);
  166. define('HEAD_MAGNIFICATION', 1.1);
  167. // Include dependancies.
  168. juimport('tcpdf.tcpdf');
  169. }
  170. /**
  171. * Parse the bookmarks in a buffer.
  172. *
  173. * @param TCPDF $doc The PDF document.
  174. * @param string $text The text to parse.
  175. * @param object $pdf The PDF data object.
  176. *
  177. * @return void
  178. * @since 1.0
  179. */
  180. protected static function parseBookmarks(TCPDF $doc, $text, $pdf)
  181. {
  182. // Find any bookmarks in the page.
  183. $regex = '#<!--BOOKMARK(\d)(.*)-->#U';
  184. // Find the bookmark comments.
  185. $matches = array();
  186. preg_match_all($regex, $text, $matches, PREG_SET_ORDER);
  187. if (!empty($matches)) {
  188. // Split the text around the bookmark.
  189. $parts = preg_split($regex, $text);
  190. foreach ($parts as $n => $part)
  191. {
  192. if (trim($part) == '') {
  193. continue;
  194. }
  195. if (isset($matches[$n-1])) {
  196. $doc->Bookmark($matches[$n-1][2], $matches[$n-1][1], 0);
  197. }
  198. else {
  199. $doc->Bookmark(JText::sprintf('COM_ARTOFPDF_PDF_BOOKMARK_N', $n), 0, 0);
  200. }
  201. if ($pdf->style) {
  202. $part = '<style>'.$pdf->style.'</style>'.$part;
  203. }
  204. $doc->WriteHTML($part, true, false, true, true, '');
  205. }
  206. }
  207. // No bookmarks to just add the text.
  208. else {
  209. if ($pdf->style) {
  210. $text = '<style>'.$pdf->style.'</style>'.$text;
  211. }
  212. $doc->WriteHTML($text, true, false, true, true, '');
  213. }
  214. }
  215. /**
  216. * Parse the pages in a buffer.
  217. *
  218. * @param TCPDF $doc The PDF document.
  219. * @param string $text The text to parse.
  220. * @param object $pdf The PDF data object.
  221. *
  222. * @return void
  223. * @since 1.0
  224. */
  225. protected static function parsePages(TCPDF $doc, $text, $pdf)
  226. {
  227. // Explode the buffer on the new page marker.
  228. $pages = explode('<!--NEWPAGE-->', $text);
  229. foreach ($pages as $page)
  230. {
  231. if (trim($page) == '') {
  232. continue;
  233. }
  234. $doc->AddPage();
  235. self::parseBookmarks($doc, $page, $pdf);
  236. }
  237. }
  238. /**
  239. * Method to test whether a record can be deleted.
  240. *
  241. * @param object $record A record object.
  242. *
  243. * @return boolean True if allowed to delete the record. Defaults to the permission set in the component.
  244. * @since 1.0
  245. */
  246. protected function canDelete($record)
  247. {
  248. return true;
  249. }
  250. /**
  251. * Method to test whether a record can be deleted.
  252. *
  253. * @param object $record A record object.
  254. *
  255. * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component.
  256. * @since 1.0
  257. */
  258. protected function canEditState($record)
  259. {
  260. return true;
  261. }
  262. /**
  263. * Method to duplicate PDF's.
  264. *
  265. * @param array An array of primary key IDs.
  266. *
  267. * @return boolean True if successful.
  268. * @throws Exception
  269. */
  270. public function duplicate(&$pks)
  271. {
  272. // Initialise variables.
  273. $user = JFactory::getUser();
  274. $db = $this->getDbo();
  275. // Access checks.
  276. // if (!$user->authorise('core.create', 'com_artofpdf')) {
  277. // throw new Exception(JText::_('JERROR_CORE_CREATE_NOT_PERMITTED'));
  278. // }
  279. $table = $this->getTable();
  280. foreach ($pks as $pk)
  281. {
  282. if ($table->load($pk, true)) {
  283. // Reset the id to create a new record.
  284. $table->id = 0;
  285. // Alter the title.
  286. $m = null;
  287. if (preg_match('#\((\d+)\)$#', $table->title, $m)) {
  288. $table->title = preg_replace('#\(\d+\)$#', '('.($m[1] + 1).')', $table->title);
  289. }
  290. else {
  291. $table->title .= ' (2)';
  292. }
  293. if (!$table->check() || !$table->store()) {
  294. throw new Exception($table->getError());
  295. }
  296. }
  297. else {
  298. throw new Exception($table->getError());
  299. }
  300. }
  301. return true;
  302. }
  303. /**
  304. * Method to get a Pdf.
  305. *
  306. * @param integer An optional id of the object to get, otherwise the id from the model state is used.
  307. * @return mixed Category data object on success, false on failure.
  308. * @since 1.6
  309. */
  310. public function getItem($pk = null)
  311. {
  312. if ($result = parent::getItem($pk)) {
  313. $result->params->loadSetupFile(dirname(__FILE__).'/forms/pdf.xml');
  314. /*
  315. // Convert the created and modified dates to local user time for display in the form.
  316. jimport('joomla.utilities.date');
  317. $tz = new DateTimeZone(JFactory::getApplication()->getCfg('offset'));
  318. if (intval($result->created_time)) {
  319. $date = new JDate($result->created_time);
  320. $date->setTimezone($tz);
  321. $result->created_time = $date->toMySQL(true);
  322. } else {
  323. $result->created_time = null;
  324. }
  325. if (intval($result->modified_time)) {
  326. $date = new JDate($result->modified_time);
  327. $date->setTimezone($tz);
  328. $result->modified_time = $date->toMySQL(true);
  329. } else {
  330. $result->modified_time = null;
  331. }
  332. */
  333. }
  334. return $result;
  335. }
  336. /**
  337. * Returns a reference to the a Table object, always creating it.
  338. *
  339. * @param type $type The table type to instantiate
  340. * @param string $prefix A prefix for the table class name.
  341. * @param array $config Configuration array for model.
  342. *
  343. * @return JTable A database object
  344. * @since 1.0
  345. */
  346. public function getTable($type = 'Pdf', $prefix = 'ArtofPdfTable', $config = array())
  347. {
  348. return JTable::getInstance($type, $prefix, $config);
  349. }
  350. /**
  351. * Make the PDF.
  352. *
  353. * Note: This method is inspired by the JDocumentPdf class and other examples from the TCPDF site.
  354. *
  355. * @param object $pdf
  356. * @param string $html
  357. *
  358. * @return boolean
  359. * @since 1.0
  360. */
  361. public function make(&$pdf, &$buffer)
  362. {
  363. // Initialise variables.
  364. $user = JFactory::getUser();
  365. $pdf->params->def('header_title', $pdf->title);
  366. $doc = self::getPdfDocument($pdf->params);
  367. $doc->SetTitle(
  368. $pdf->title
  369. );
  370. $doc->SetSubject(
  371. $pdf->subject
  372. );
  373. $doc->SetKeywords(
  374. $pdf->keywords
  375. );
  376. // PHP doesn't handle relative paths if soft links are involved to this component.
  377. // TODO Add optional switch for this.
  378. if (strpos($buffer, '<img') !== false) {
  379. $regex = "#(<img\s[^>]*src\s*=\s*['\"]?)(images/)([^>]*?>)#is";
  380. $replace = '$1'.JPATH_ROOT.'/$2$3';
  381. $buffer = preg_replace($regex, $replace, $buffer);
  382. }
  383. // if ($pdf->style) {
  384. // $buffer = '<style>'.$pdf->style.'</style>'.$buffer;
  385. // }
  386. self::parsePages($doc, $buffer, $pdf);
  387. self::addPdfToc($doc, $pdf->params);
  388. //Close and output PDF document
  389. $doc->Output(JPATH_SITE.'/tmp/'.$pdf->title.'.pdf', 'F');
  390. jimport('joomla.filesystem.file');
  391. JFile::write(JPATH_SITE.'/tmp/'.$pdf->title.'.html', '<html><body>'.$buffer.'</html></body>');
  392. // Update the build stamp.
  393. jimport('joomla.utilities.date');
  394. $db = $this->getDbo();
  395. $query = new JDatabaseQuery;
  396. $now = new JDate;
  397. $query->update('#__artof_pdfs');
  398. $query->set('`build_time` = '.$db->quote($now->toMySQL()));
  399. $query->where('`id` = '.(int) $pdf->id);
  400. $db->setQuery((string) $query);
  401. if (!$db->query()) {
  402. throw new Exception($db->getErrorMsg());
  403. }
  404. }
  405. /**
  406. * Prepare and sanitise the table prior to saving.
  407. *
  408. * @param JTable $table The table object for the record.
  409. *
  410. * @return boolean True if successful, otherwise false and the error is set.
  411. * @since 1.0
  412. */
  413. protected function prepareTable($table)
  414. {
  415. }
  416. }