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::view
  • alpha::view::renderers
  • alpha::view::widgets

Classes

  • AlphaAgentUtils
  • AlphaAutoLoader
  • AlphaBackUpUtils
  • AlphaConfig
  • AlphaCronManager
  • AlphaErrorHandlers
  • AlphaFileUtils
  • AlphaImageUtils
  • AlphaKPI
  • AlphaMarkdown
  • 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 1550 2012-07-29 21:15:40Z alphadevx $
 14:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
 15:  * @copyright Copyright (c) 2012, 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 = strpos($attachmentURL, '/');
129:             $end = strrpos($attachmentURL, '"');
130:             $fileName = 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 = strpos($attachmentURL, '/');
143:             $end = strrpos($attachmentURL, '" alt');
144:             $fileName = 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: ?>
Alpha Framework ${alpha.version.new} API Documentation API documentation generated by ApiGen 2.8.0