Overview

Packages

  • alpha::controller
  • alpha::controller::front
  • alpha::exceptions
  • alpha::model
  • alpha::model::types
  • alpha::tasks
  • alpha::tests
  • alpha::util
  • alpha::util::cache
  • alpha::util::codehighlight
  • alpha::util::convertors
  • alpha::util::feeds
  • alpha::util::filters
  • alpha::util::graphs
  • alpha::util::helpers
  • alpha::util::metrics
  • alpha::util::search
  • alpha::view
  • alpha::view::renderers
  • alpha::view::widgets

Classes

  • AlphaAgentUtils
  • AlphaAutoLoader
  • AlphaBackUpUtils
  • AlphaConfig
  • AlphaCronManager
  • AlphaErrorHandlers
  • AlphaFileUtils
  • AlphaImageUtils
  • AlphaKPI
  • AlphaMarkdown
  • AlphaPHPServerUtils
  • AlphaSecurityUtils
  • AlphaTCPDF
  • InputFilter
  • LogFile
  • Logger
  • MarkdownFacade
  • TCPDFFacade

Interfaces

  • AlphaTaskInterface
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: AlphaAutoLoader::loadLib('eng.php');
  4: 
  5: /**
  6:  *
  7:  * A facade class for the TCPDF library which is used to convert some HTML content provided by the
  8:  * Markdown library to a PDF file using FPDF
  9:  *
 10:  * @package alpha::util
 11:  * @since 1.0
 12:  * @author John Collins <dev@alphaframework.org>
 13:  * @version $Id: TCPDFFacade.inc 1693 2013-12-09 23:33:24Z alphadevx $
 14:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
 15:  * @copyright Copyright (c) 2013, John Collins (founder of Alpha Framework).
 16:  * All rights reserved.
 17:  *
 18:  * <pre>
 19:  * Redistribution and use in source and binary forms, with or
 20:  * without modification, are permitted provided that the
 21:  * following conditions are met:
 22:  *
 23:  * * Redistributions of source code must retain the above
 24:  *   copyright notice, this list of conditions and the
 25:  *   following disclaimer.
 26:  * * Redistributions in binary form must reproduce the above
 27:  *   copyright notice, this list of conditions and the
 28:  *   following disclaimer in the documentation and/or other
 29:  *   materials provided with the distribution.
 30:  * * Neither the name of the Alpha Framework nor the names
 31:  *   of its contributors may be used to endorse or promote
 32:  *   products derived from this software without specific
 33:  *   prior written permission.
 34:  *
 35:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 36:  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 37:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 38:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 39:  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 40:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 41:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 42:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 43:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 44:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 45:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 46:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 47:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 48:  * </pre>
 49:  *
 50:  */
 51: class TCPDFFacade {
 52:     /**
 53:      * The HTML-format content that we will render as a PDF
 54:      *
 55:      * @var string
 56:      * @since 1.0
 57:      */
 58:     private $content;
 59: 
 60:     /**
 61:      * The PDF object that will be generated from the Markdown HTML content
 62:      *
 63:      * @var AlphaTCPDF
 64:      * @since 1.0
 65:      */
 66:     private $pdf;
 67: 
 68:     /**
 69:      * The business object that stores the content will be rendered to Markdown
 70:      *
 71:      * @var AlphaDAO
 72:      * @since 1.0
 73:      */
 74:     private $BO = null;
 75: 
 76:     /**
 77:      * The auto-generated name of the PDF cache file for the BO
 78:      *
 79:      * @var string
 80:      * @since 1.0
 81:      */
 82:     private $PDFFilename;
 83: 
 84:     /**
 85:      * The auto-generated name of the HTML cache file for the BO generated by Markdown
 86:      *
 87:      * @var string
 88:      * @since 1.0
 89:      */
 90:     private $HTMLFilename;
 91: 
 92:     /**
 93:      * The constructor
 94:      *
 95:      * @param object $BO the business object that stores the content will be rendered to Markdown
 96:      * @since 1.0
 97:      */
 98:     public function __construct($BO) {
 99:         global $config;
100:         global $l;
101: 
102:         $this->BO = $BO;
103:         $this->PDFFilename = $config->get('app.file.store.dir').'cache/pdf/'.get_class($this->BO).'_'.$this->BO->getID().'_'.$this->BO->getVersion().'.pdf';
104:         $PDFDownloadName = str_replace(' ', '_', $this->BO->get('title').'.pdf');
105:         $this->HTMLFilename = $config->get('app.file.store.dir').'cache/html/'.get_class($this->BO).'_'.$this->BO->getID().'_'.$this->BO->getVersion().'.html';
106: 
107:         // first check the PDF cache, and if its there then re-direct to the file
108:         if($this->checkPDFCache())
109:             $this->serveCachedPDF($PDFDownloadName);
110: 
111:         if(method_exists($this->BO, 'getAttachmentsURL'))
112:             $attachURL = $this->BO->getAttachmentsURL();
113:         else
114:             $attachURL = '';
115: 
116:         if ($this->checkHTMLCache()) {
117:             $this->loadHTMLCache();
118:         }else{
119:             $this->content = $this->markdown($this->BO->get('content', true), $attachURL);
120:             $this->HTMLCache();
121:         }
122: 
123:         // Replace all instances of $attachURL in link tags to links to the ViewAttachment controller
124:         $attachments = array();
125:         preg_match_all('/href\=\"\$attachURL\/.*\"/', $this->content, $attachments);
126: 
127:         foreach($attachments[0] as $attachmentURL) {
128:             $start = mb_strpos($attachmentURL, '/');
129:             $end = mb_strrpos($attachmentURL, '"');
130:             $fileName = mb_substr($attachmentURL, $start+1, $end-($start+1));
131: 
132:             if(method_exists($this->BO, 'getAttachmentSecureURL')) {
133:                 $this->content = str_replace($attachmentURL, 'href='.$this->BO->getAttachmentSecureURL($fileName), $this->content);
134:             }
135:         }
136: 
137:         // Handle image attachments
138:         $attachments = array();
139:         preg_match_all('/\<img\ src\=\"\$attachURL\/.*\".*\>/', $this->content, $attachments);
140: 
141:         foreach($attachments[0] as $attachmentURL) {
142:             $start = mb_strpos($attachmentURL, '/');
143:             $end = mb_strrpos($attachmentURL, '" alt');
144:             $fileName = mb_substr($attachmentURL, $start+1, $end-($start+1));
145: 
146:             if($config->get('cms.images.widget')) {
147:                 // get the details of the source image
148:                 $path = $this->BO->getAttachmentsLocation().'/'.$fileName;
149:                 $image_details = getimagesize($path);
150:                 $imgType = $image_details[2];
151:                 if($imgType == 1)
152:                     $type = 'gif';
153:                 elseif($imgType == 2)
154:                     $type = 'jpg';
155:                 elseif($imgType == 3)
156:                     $type = 'png';
157: 
158:                 $img = new Image($path, $image_details[0], $image_details[1], $type, 0.95, false, (boolean)$config->get('cms.images.widget.secure'));
159:                 $this->content = str_replace($attachmentURL, $img->renderHTMLLink(), $this->content);
160:             }else{
161:                 // render a normal image link to the ViewAttachment controller
162:                 if(method_exists($this->BO, 'getAttachmentSecureURL')) {
163:                     $this->content = str_replace($attachmentURL, '<img src="'.$this->BO->getAttachmentSecureURL($fileName).'">', $this->content);
164:                 }
165:             }
166:         }
167: 
168:         $this->pdf = new AlphaTCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
169:         $this->pdf->SetCreator(PDF_CREATOR);
170:         $this->pdf->SetAuthor($this->BO->get('author'));
171:         $this->pdf->SetTitle($this->BO->get('title'));
172:         $this->pdf->SetSubject($this->BO->get('description'));
173:         // TODO inject tags here?
174:         //$this->pdf->SetKeywords($this->BO->get('keywords'));
175: 
176:         //set margins
177:         $this->pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
178:         $this->pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
179:         $this->pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
180: 
181:         //set auto page breaks
182:         $this->pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
183: 
184:         //set image scale factor
185:         $this->pdf->setImageScale(2.5);
186: 
187:         //set some language-dependent strings
188:         $this->pdf->setLanguageArray($l);
189: 
190:         // add a page
191:         $this->pdf->AddPage();
192: 
193:         // add the title
194:         $title = '<h1>'.$this->BO->get('title').'</h1>';
195:         // add some custom footer info about the article
196:         $footer = '<br><p>Article URL: <a href="'.$this->BO->get('URL').'">'.$this->BO->get('URL').'</a><br>Title: '.$this->BO->get('title').'<br>Author: '.$this->BO->get('author').'</p>';
197: 
198:         // write the title
199:         $this->pdf->writeHTML($title, true, 0, true, 0);
200:         // output the HTML content
201:         $this->pdf->writeHTML($this->content, true, 0, true, 0);
202:         // write the article footer
203:         $this->pdf->writeHTML($footer, true, 0, true, 0);
204: 
205:         // save this PDF to the cache
206:         $this->pdf->Output($this->PDFFilename, 'F');
207:         $this->serveCachedPDF($PDFDownloadName);
208:     }
209: 
210:     /**
211:      * Facade method which will invoke our custom markdown class rather than the standard one
212:      *
213:      * @since 1.0
214:      */
215:      private function markdown($text, $attachURL='') {
216:         global $config;
217: 
218:         /*
219:          * Initialize the parser and return the result of its transform method.
220:          *
221:          */
222:         static $parser;
223:         if (!isset($parser)) {
224:             $parser_class = 'AlphaMarkdown';
225:             $parser = new $parser_class;
226:         }
227: 
228:         /*
229:          * Replace all instances of $sysURL in the text with the app.url setting from config
230:          *
231:          */
232:         $text = str_replace('$sysURL', $config->get('app.url'), $text);
233: 
234:         // transform text using parser.
235:         return $parser->transform($text);
236:     }
237: 
238:     /**
239:      * Fetter for the content
240:      *
241:      * @return string HTML rendered the content
242:      * @since 1.0
243:      */
244:     public function getContent() {
245:         return $this->content;
246:     }
247: 
248:     /**
249:      * Saves the HTML generated by Markdown to the cache directory
250:      *
251:      * @since 1.0
252:      */
253:     private function HTMLCache() {
254:         // check to ensure that the article is not transient before caching it
255:         if ($this->BO->getID() != '00000000000') {
256:             $fp=fopen($this->HTMLFilename,"w");
257:             if (!$fp) {
258:                 throw new AlphaException('Failed to open the cache file for writing, directory permissions my not be set correctly!');
259:             }else{
260:                 flock($fp,2); // locks the file for writting
261:                 fwrite($fp,$this->content);
262:                 flock($fp,3); // unlocks the file
263:                 fclose($fp); //closes the file
264:             }
265:         }
266:     }
267: 
268:     /**
269:      * Used to check the HTML cache for the BO cache file
270:      *
271:      * @return bool true if the file exists, false otherwise
272:      * @since 1.0
273:      */
274:     private function checkHTMLCache() {
275:         global $config;
276: 
277:         return file_exists($this->HTMLFilename);
278:     }
279: 
280:     /**
281:      * Method to load the content of the cache file to the $content attribute of this object
282:      *
283:      * @since 1.0
284:      */
285:     private function loadHTMLCache() {
286:         $fp = fopen($this->HTMLFilename,"r");
287: 
288:         if (!$fp) {
289:             throw new AlphaException('Failed to open the cache file for reading, directory permissions my not be set correctly!' ,'loadHTMLCache()');
290:         }else{
291:             $this->content = fread($fp, filesize($this->HTMLFilename));
292:             fclose($fp); //closes the file
293:         }
294:     }
295: 
296:     /**
297:      * Used to check the PDF cache for the BO cache file
298:      *
299:      * @return bool true if the file exists, false otherwise
300:      * @since 1.0
301:      */
302:     private function checkPDFCache() {
303:         return file_exists($this->PDFFilename);
304:     }
305: 
306:     /**
307:      * Used to serve the cached PDF file as a download
308:      *
309:      * @since 1.0
310:      */
311:     private function serveCachedPDF($name) {
312:         // first load the file
313:         $handle = fopen ($this->PDFFilename, 'r');
314:         $data = fread($handle, filesize($this->PDFFilename));
315:         fclose($handle);
316: 
317:         $filesize = strlen($data);
318:         $mimetype = 'application/octet-stream';
319: 
320:         // Start sending headers
321:         header("Pragma: public"); // required
322:         header("Expires: 0");
323:         header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
324:         header("Cache-Control: private",false); // required for certain browsers
325:         header("Content-Transfer-Encoding: binary");
326:         header("Content-Type: " . $mimetype);
327:         header("Content-Length: " . $filesize);
328:         header("Content-Disposition: attachment; filename=\"" . $name . "\";" );
329: 
330:         // Send data
331:         echo $data;
332:         die();
333:     }
334: }
335: 
336: ?>
Alpha Framework 1.2.4 API Documentation API documentation generated by ApiGen 2.8.0