PageRenderTime 52ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/vivoManagement/app/Plugin/CakePdf/Pdf/CakePdf.php

https://bitbucket.org/vsposato/vivo-tools
PHP | 720 lines | 334 code | 79 blank | 307 comment | 61 complexity | 6a3db7e0f0faa4560bad7008c9c545b0 MD5 | raw file
  1. <?php
  2. App::uses('File', 'Utility');
  3. App::uses('View', 'View');
  4. class CakePdf {
  5. /**
  6. * Layout for the View
  7. *
  8. * @var string
  9. */
  10. protected $_layout = 'default';
  11. /**
  12. * Template for the view
  13. *
  14. * @var string
  15. */
  16. protected $_template = null;
  17. /**
  18. * View for render
  19. *
  20. * @var string
  21. */
  22. protected $_viewRender = 'View';
  23. /**
  24. * Vars to sent to render
  25. *
  26. * @var array
  27. */
  28. protected $_viewVars = array();
  29. /**
  30. * Theme for the View
  31. *
  32. * @var array
  33. */
  34. protected $_theme = null;
  35. /**
  36. * Helpers to be used in the render
  37. *
  38. * @var array
  39. */
  40. protected $_helpers = array('Html');
  41. /**
  42. * Instance of PdfEngine class
  43. *
  44. * @var AbstractPdfEngine
  45. */
  46. protected $_engineClass = null;
  47. /**
  48. * Instance of PdfCrypto class
  49. *
  50. * @var AbstractPdfCrypto
  51. */
  52. protected $_cryptoClass = null;
  53. /**
  54. * Html to be rendered
  55. *
  56. * @var string
  57. */
  58. protected $_html = null;
  59. /**
  60. * Page size of the pdf
  61. *
  62. * @var string
  63. */
  64. protected $_pageSize = 'A4';
  65. /**
  66. * Orientation of the pdf
  67. *
  68. * @var string
  69. */
  70. protected $_orientation = 'portrait';
  71. /**
  72. * Encoding
  73. *
  74. * @var string
  75. */
  76. protected $_encoding = 'UTF-8';
  77. /**
  78. * Bottom margin in mm
  79. *
  80. * @var number
  81. */
  82. protected $_marginBottom = null;
  83. /**
  84. * Left margin in mm
  85. *
  86. * @var number
  87. */
  88. protected $_marginLeft = null;
  89. /**
  90. * Right margin in mm
  91. *
  92. * @var number
  93. */
  94. protected $_marginRight = null;
  95. /**
  96. * Top margin in mm
  97. *
  98. * @var number
  99. */
  100. protected $_marginTop = null;
  101. /**
  102. * Title of the document
  103. *
  104. * @var string
  105. */
  106. protected $_title = null;
  107. /**
  108. * Flag that tells if we need to pass it through crypto
  109. *
  110. * @var boolean
  111. */
  112. protected $_protect = false;
  113. /**
  114. * User password, used with crypto
  115. *
  116. * @var boolean
  117. */
  118. protected $_userPassword = null;
  119. /**
  120. * Owner password, used with crypto
  121. *
  122. * @var boolean
  123. */
  124. protected $_ownerPassword = null;
  125. /**
  126. * Cache config name, if set to false cache is disabled
  127. *
  128. * @var string|boolean
  129. */
  130. protected $_cache = false;
  131. /**
  132. * Permissions that are allowed, used with crypto
  133. *
  134. * false: none
  135. * true: all
  136. * array: List of permissions that are allowed
  137. *
  138. * @var mixed
  139. */
  140. protected $_allow = false;
  141. /**
  142. * Available permissions
  143. *
  144. * @var array
  145. */
  146. private $__availablePermissions = array(
  147. 'print',
  148. 'degraded_print',
  149. 'modify',
  150. 'assembly',
  151. 'copy_contents',
  152. 'screen_readers',
  153. 'annotate',
  154. 'fill_in'
  155. );
  156. /**
  157. * Constructor
  158. *
  159. * @param array $config Pdf configs to use
  160. */
  161. public function __construct($config = array()) {
  162. $config = array_merge(array(
  163. 'engine' => Configure::read('Pdf.engine'),
  164. 'crypto' => Configure::read('Pdf.crypto')
  165. ), $config);
  166. if ($config['engine']) {
  167. $this->engine($config['engine'])->config($config);
  168. }
  169. if ($config['crypto']) {
  170. $this->crypto($config['crypto'])->config($config);
  171. }
  172. $options = array('pageSize', 'orientation', 'margin', 'title', 'encoding', 'protect', 'userPassword', 'ownerPassword', 'permissions', 'cache');
  173. foreach ($options as $option) {
  174. if (isset($config[$option])) {
  175. $this->{$option}($config[$option]);
  176. }
  177. }
  178. }
  179. /**
  180. * Create pdf content from html. Can be used to write to file or with PdfView to display
  181. *
  182. * @param mixed $html Html content to render. If left empty, the template will be rendered with viewVars and layout that have been set.
  183. * @return string
  184. */
  185. public function output($html = null) {
  186. $Engine = $this->engine();
  187. if (!$Engine) {
  188. throw new CakeException(__d('cake_pdf', 'Engine is not loaded'));
  189. }
  190. if (!$html) {
  191. $html = $this->_render();
  192. }
  193. $this->html($html);
  194. $cache = $this->cache();
  195. if ($cache) {
  196. $cacheKey = md5(serialize($this));
  197. $cached = Cache::read($cacheKey, $cache);
  198. if ($cached) {
  199. return $cached;
  200. }
  201. }
  202. $output = $Engine->output();
  203. if ($this->protect()) {
  204. $output = $this->crypto()->encrypt($output);
  205. }
  206. if ($cache) {
  207. Cache::write($cacheKey, $output, $cache);
  208. }
  209. return $output;
  210. }
  211. /**
  212. * Get/Set Html.
  213. *
  214. * @param null|string $html
  215. * @return mixed
  216. */
  217. public function html($html = null) {
  218. if ($html === null) {
  219. return $this->_html;
  220. }
  221. $this->_html = $html;
  222. return $this;
  223. }
  224. /**
  225. * Writes output to file
  226. *
  227. * @param srting $destination Absolute file path to write to
  228. * @param boolean $create Create file if it does not exist (if true)
  229. * @return boolean
  230. */
  231. public function write($destination, $create = true, $html = null) {
  232. $output = $this->output($html);
  233. $File = new File($destination, $create);
  234. return $File->write($output) && $File->close();
  235. }
  236. /**
  237. * Load PdfEngine
  238. *
  239. * @param string $name Classname of pdf engine without `Engine` suffix. For example `CakePdf.DomPdf`
  240. * @return object PdfEngine
  241. */
  242. public function engine($name = null) {
  243. if (!$name) {
  244. return $this->_engineClass;
  245. }
  246. list($pluginDot, $engineClassName) = pluginSplit($name, true);
  247. $engineClassName = $engineClassName . 'Engine';
  248. App::uses($engineClassName, $pluginDot . 'Pdf/Engine');
  249. if (!class_exists($engineClassName)) {
  250. throw new CakeException(__d('cake_pdf', 'Pdf engine "%s" not found', $name));
  251. }
  252. if (!is_subclass_of($engineClassName, 'AbstractPdfEngine')) {
  253. throw new CakeException(__d('cake_pdf', 'Pdf engines must extend "AbstractPdfEngine"'));
  254. }
  255. $this->_engineClass = new $engineClassName($this);
  256. return $this->_engineClass;
  257. }
  258. /**
  259. * Load PdfCrypto
  260. *
  261. * @param string $name Classname of crypto engine without `Crypto` suffix. For example `CakePdf.Pdftk`
  262. * @return object PdfCrypto
  263. */
  264. public function crypto($name = null) {
  265. if ($name === null) {
  266. if ($this->_cryptoClass) {
  267. return $this->_cryptoClass;
  268. }
  269. throw new CakeException(__d('cake_pdf', 'Crypto is not loaded'));
  270. }
  271. list($pluginDot, $engineClassName) = pluginSplit($name, true);
  272. $engineClassName = $engineClassName . 'Crypto';
  273. App::uses($engineClassName, $pluginDot . 'Pdf/Crypto');
  274. if (!class_exists($engineClassName)) {
  275. throw new CakeException(__d('cake_pdf', 'Pdf crypto "%s" not found', $name));
  276. }
  277. if (!is_subclass_of($engineClassName, 'AbstractPdfCrypto')) {
  278. throw new CakeException(__d('cake_pdf', 'Crypto engine must extend "AbstractPdfCrypto"'));
  279. }
  280. $this->_cryptoClass = new $engineClassName($this);
  281. return $this->_cryptoClass;
  282. }
  283. /**
  284. * Get/Set Page size.
  285. *
  286. * @param null|string $pageSize
  287. * @return mixed
  288. */
  289. public function pageSize($pageSize = null) {
  290. if ($pageSize === null) {
  291. return $this->_pageSize;
  292. }
  293. $this->_pageSize = $pageSize;
  294. return $this;
  295. }
  296. /**
  297. * Get/Set Orientation.
  298. *
  299. * @param null|string $orientation
  300. * @return mixed
  301. */
  302. public function orientation($orientation = null) {
  303. if ($orientation === null) {
  304. return $this->_orientation;
  305. }
  306. $this->_orientation = $orientation;
  307. return $this;
  308. }
  309. /**
  310. * Get/Set Encoding.
  311. *
  312. * @param null|string $encoding
  313. * @return mixed
  314. */
  315. public function encoding($encoding = null) {
  316. if ($encoding === null) {
  317. return $this->_encoding;
  318. }
  319. $this->_encoding = $encoding;
  320. return $this;
  321. }
  322. /**
  323. * Get/Set page margins.
  324. *
  325. * Several options are available
  326. *
  327. * Array format
  328. * ------------
  329. * First param can be an array with the following options:
  330. * - bottom
  331. * - left
  332. * - right
  333. * - top
  334. *
  335. * Set margin for all borders
  336. * --------------------------
  337. * $bottom is set to a string
  338. * Leave all other parameters empty
  339. *
  340. * Set margin for horizontal and vertical
  341. * --------------------------------------
  342. * $bottom value will be set to bottom and top
  343. * $left value will be set to left and right
  344. *
  345. * @param null|string|array $bottom
  346. * @param null|string $left
  347. * @param null|string $right
  348. * @param null|string $top
  349. * @return mixed
  350. */
  351. public function margin($bottom = null, $left = null, $right = null, $top = null) {
  352. if ($bottom === null) {
  353. return array(
  354. 'bottom' => $this->_marginBottom,
  355. 'left' => $this->_marginLeft,
  356. 'right' => $this->_marginRight,
  357. 'top' => $this->_marginTop
  358. );
  359. }
  360. if (is_array($bottom)) {
  361. extract($bottom, EXTR_IF_EXISTS);
  362. }
  363. if ($bottom && $left === null && $right === null && $top === null) {
  364. $left = $right = $top = $bottom;
  365. }
  366. if ($bottom && $top === null) {
  367. $top = $bottom;
  368. }
  369. if ($left && $right === null) {
  370. $right = $left;
  371. }
  372. $this->marginBottom($bottom);
  373. $this->marginLeft($left);
  374. $this->marginRight($right);
  375. $this->marginTop($top);
  376. return $this;
  377. }
  378. /**
  379. * Get/Set bottom margin.
  380. *
  381. * @param null|string $margin
  382. * @return mixed
  383. */
  384. public function marginBottom($margin = null) {
  385. if ($margin === null) {
  386. return $this->_marginBottom;
  387. }
  388. $this->_marginBottom = $margin;
  389. return $this;
  390. }
  391. /**
  392. * Get/Set left margin.
  393. *
  394. * @param null|string $margin
  395. * @return mixed
  396. */
  397. public function marginLeft($margin = null) {
  398. if ($margin === null) {
  399. return $this->_marginLeft;
  400. }
  401. $this->_marginLeft = $margin;
  402. return $this;
  403. }
  404. /**
  405. * Get/Set right margin.
  406. *
  407. * @param null|string $margin
  408. * @return mixed
  409. */
  410. public function marginRight($margin = null) {
  411. if ($margin === null) {
  412. return $this->_marginRight;
  413. }
  414. $this->_marginRight = $margin;
  415. return $this;
  416. }
  417. /**
  418. * Get/Set bottom margin.
  419. *
  420. * @param null|string $margin
  421. * @return mixed
  422. */
  423. public function marginTop($margin = null) {
  424. if ($margin === null) {
  425. return $this->_marginTop;
  426. }
  427. $this->_marginTop = $margin;
  428. return $this;
  429. }
  430. /**
  431. * Get/Set document title.
  432. *
  433. * @param null|string $title
  434. * @return mixed
  435. */
  436. public function title($title = null) {
  437. if ($title === null) {
  438. return $this->_title;
  439. }
  440. $this->_title = $title;
  441. return $this;
  442. }
  443. /**
  444. * Get/Set protection.
  445. *
  446. * @param null|boolean $protect
  447. * @return mixed
  448. */
  449. public function protect($protect = null) {
  450. if ($protect === null) {
  451. return $this->_protect;
  452. }
  453. $this->_protect = $protect;
  454. return $this;
  455. }
  456. /**
  457. * Get/Set userPassword
  458. *
  459. * The user password is used to control who can open the PDF document.
  460. *
  461. * @param null|string $password
  462. * @return mixed
  463. */
  464. public function userPassword($password = null) {
  465. if ($password === null) {
  466. return $this->_userPassword;
  467. }
  468. $this->_userPassword = $password;
  469. return $this;
  470. }
  471. /**
  472. * Get/Set ownerPassword.
  473. *
  474. * The owner password is used to control who can modify, print, manage the PDF document.
  475. *
  476. * @param null|string $password
  477. * @return mixed
  478. */
  479. public function ownerPassword($password = null) {
  480. if ($password === null) {
  481. return $this->_ownerPassword;
  482. }
  483. $this->_ownerPassword = $password;
  484. return $this;
  485. }
  486. /**
  487. * Get/Set permissions.
  488. *
  489. * all: allow all permissions
  490. * none: allow no permissions
  491. * array: list of permissions that are allowed
  492. *
  493. * @param null|bool|array $permissions
  494. * @return mixed
  495. */
  496. public function permissions($permissions = null) {
  497. if (!$this->protect()) {
  498. return $this;
  499. }
  500. if ($permissions === null) {
  501. return $this->_allow;
  502. }
  503. if (is_string($permissions) && $permissions == 'all') {
  504. $permissions = true;
  505. }
  506. if (is_string($permissions) && $permissions == 'none') {
  507. $permissions = false;
  508. }
  509. if (is_array($permissions)) {
  510. foreach ($permissions as $permission) {
  511. if (!in_array($permission, $this->__availablePermissions)) {
  512. throw new CakeException(sprintf('Invalid permission: %s', $permission));
  513. }
  514. if (!$this->crypto()->permissionImplemented($permission)) {
  515. throw new CakeException(sprintf('Permission not implemented in crypto engine: %s', $permission));
  516. }
  517. }
  518. }
  519. $this->_allow = $permissions;
  520. return $this;
  521. }
  522. /**
  523. * Get/Set caching.
  524. *
  525. * @param null|boolean|string $cache Cache config name to use, If true is passed, 'cake_pdf' will be used.
  526. * @return mixed
  527. */
  528. public function cache($cache = null) {
  529. if ($cache === null) {
  530. return $this->_cache;
  531. }
  532. if ($cache === false) {
  533. $this->_cache = false;
  534. return $this;
  535. }
  536. if ($cache === true) {
  537. $cache = 'cake_pdf';
  538. }
  539. if (!in_array($cache, Cache::configured())) {
  540. throw new CakeException(sprintf('CakePdf cache is not configured: %s', $cache));
  541. }
  542. $this->_cache = $cache;
  543. return $this;
  544. }
  545. /**
  546. * Template and layout
  547. *
  548. * @param mixed $template Template name or null to not use
  549. * @param mixed $layout Layout name or null to not use
  550. * @return mixed
  551. */
  552. public function template($template = false, $layout = null) {
  553. if ($template === false) {
  554. return array(
  555. 'template' => $this->_template,
  556. 'layout' => $this->_layout
  557. );
  558. }
  559. $this->_template = $template;
  560. if ($layout !== null) {
  561. $this->_layout = $layout;
  562. }
  563. return $this;
  564. }
  565. /**
  566. * View class for render
  567. *
  568. * @param string $viewClass
  569. * @return mixed
  570. */
  571. public function viewRender($viewClass = null) {
  572. if ($viewClass === null) {
  573. return $this->_viewRender;
  574. }
  575. $this->_viewRender = $viewClass;
  576. return $this;
  577. }
  578. /**
  579. * Variables to be set on render
  580. *
  581. * @param array $viewVars
  582. * @return mixed
  583. */
  584. public function viewVars($viewVars = null) {
  585. if ($viewVars === null) {
  586. return $this->_viewVars;
  587. }
  588. $this->_viewVars = array_merge($this->_viewVars, (array)$viewVars);
  589. return $this;
  590. }
  591. /**
  592. * Theme to use when rendering
  593. *
  594. * @param string $theme
  595. * @return mixed
  596. */
  597. public function theme($theme = null) {
  598. if ($theme === null) {
  599. return $this->_theme;
  600. }
  601. $this->_theme = $theme;
  602. return $this;
  603. }
  604. /**
  605. * Helpers to be used in render
  606. *
  607. * @param array $helpers
  608. * @return mixed
  609. */
  610. public function helpers($helpers = null) {
  611. if ($helpers === null) {
  612. return $this->_helpers;
  613. }
  614. $this->_helpers = (array)$helpers;
  615. return $this;
  616. }
  617. /**
  618. * Build and set all the view properties needed to render the layout and template.
  619. *
  620. * @return array The rendered template wrapped in layout.
  621. */
  622. protected function _render() {
  623. $viewClass = $this->viewRender();
  624. if ($viewClass !== 'View') {
  625. list($pluginDot, $viewClass) = pluginSplit($viewClass, true);
  626. $viewClass .= 'View';
  627. App::uses($viewClass, $pluginDot . 'View');
  628. }
  629. $Controller = new Controller(new CakeRequest());
  630. $View = new $viewClass($Controller);
  631. $View->viewVars = $this->_viewVars;
  632. $View->helpers = $this->_helpers;
  633. $View->theme = $this->_theme;
  634. $View->layoutPath = 'pdf';
  635. $View->viewPath = 'Pdf';
  636. $View->view = $this->_template;
  637. $View->layout = $this->_layout;
  638. return $View->render();
  639. }
  640. }