Overview

Namespaces

  • Alpha
    • Controller
      • Front
    • Exception
    • Model
      • Type
    • Task
    • Util
      • Backup
      • Cache
      • Code
        • Highlight
        • Metric
      • Config
      • Convertor
      • Email
      • Extension
      • Feed
      • File
      • Graph
      • Helper
      • Http
        • Filter
        • Session
      • Image
      • Logging
      • Search
      • Security
    • View
      • Renderer
        • Html
        • Json
      • Widget

Classes

  • Markdown
  • MarkdownFacade
  • TCPDF
  • TCPDFFacade
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: namespace Alpha\Util\Extension;
  4: 
  5: use Alpha\Util\Config\ConfigProvider;
  6: use Alpha\View\Widget\Image;
  7: use Alpha\Exception\AlphaException;
  8: 
  9: /**
 10:  * A facade class for the Markdown library.
 11:  *
 12:  * @since 1.0
 13:  *
 14:  * @author John Collins <dev@alphaframework.org>
 15:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
 16:  * @copyright Copyright (c) 2015, John Collins (founder of Alpha Framework).
 17:  * All rights reserved.
 18:  *
 19:  * <pre>
 20:  * Redistribution and use in source and binary forms, with or
 21:  * without modification, are permitted provided that the
 22:  * following conditions are met:
 23:  *
 24:  * * Redistributions of source code must retain the above
 25:  *   copyright notice, this list of conditions and the
 26:  *   following disclaimer.
 27:  * * Redistributions in binary form must reproduce the above
 28:  *   copyright notice, this list of conditions and the
 29:  *   following disclaimer in the documentation and/or other
 30:  *   materials provided with the distribution.
 31:  * * Neither the name of the Alpha Framework nor the names
 32:  *   of its contributors may be used to endorse or promote
 33:  *   products derived from this software without specific
 34:  *   prior written permission.
 35:  *
 36:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 37:  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 38:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 39:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 40:  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 41:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 42:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 43:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 44:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 45:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 46:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 47:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 48:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 49:  * </pre>
 50:  */
 51: class MarkdownFacade
 52: {
 53:     /**
 54:      * The markdown-format content that we will render.
 55:      *
 56:      * @var string
 57:      *
 58:      * @since 1.0
 59:      */
 60:     private $content;
 61: 
 62:     /**
 63:      * The business object that stores the content will be rendered to Markdown.
 64:      *
 65:      * @var Alpha\Model\ActiveRecord
 66:      *
 67:      * @since 1.0
 68:      */
 69:     private $BO = null;
 70: 
 71:     /**
 72:      * The auto-generated name of the Markdown HTML cache file for the BO.
 73:      *
 74:      * @var string
 75:      *
 76:      * @since 1.0
 77:      */
 78:     private $filename;
 79: 
 80:     /**
 81:      * The constructor.
 82:      *
 83:      * @param Alpha\Model\ActiveRecord $BO
 84:      * @param bool                     $useCache
 85:      *
 86:      * @since 1.0
 87:      */
 88:     public function __construct($BO, $useCache = true)
 89:     {
 90:         $config = ConfigProvider::getInstance();
 91: 
 92:         $this->BO = $BO;
 93: 
 94:         if ($this->BO instanceof \Alpha\Model\Article && $this->BO->isLoadedFromFile()) {
 95:             $underscoreTimeStamp = str_replace(array('-', ' ', ':'), '_', $this->BO->getContentFileDate());
 96:             $this->filename = $config->get('app.file.store.dir').'cache/html/'.get_class($this->BO).'_'.$this->BO->get('title').'_'.$underscoreTimeStamp.'.html';
 97:         } else {
 98:             $this->filename = $config->get('app.file.store.dir').'cache/html/'.get_class($this->BO).'_'.$this->BO->getID().'_'.$this->BO->getVersion().'.html';
 99:         }
100: 
101:         if (!$useCache) {
102:             $this->content = $this->markdown($this->BO->get('content', true));
103:         } else {
104:             if ($this->checkCache()) {
105:                 $this->loadCache();
106:             } else {
107:                 if ($this->BO->get('content', true) == '') {
108:                     // the content may not be loaded from the DB at this stage due to a previous soft-load
109:                     $this->BO->reload();
110:                 }
111: 
112:                 $this->content = $this->markdown($this->BO->get('content', true));
113: 
114:                 $this->cache();
115:             }
116:         }
117: 
118:         // Replace all instances of $attachURL in link tags to links to the ViewAttachment controller
119:         $attachments = array();
120:         preg_match_all('/href\=\"\$attachURL\/.*\"/', $this->content, $attachments);
121: 
122:         foreach ($attachments[0] as $attachmentURL) {
123:             $start = mb_strpos($attachmentURL, '/');
124:             $end = mb_strrpos($attachmentURL, '"');
125:             $fileName = mb_substr($attachmentURL, $start + 1, $end - ($start + 1));
126: 
127:             if (method_exists($this->BO, 'getAttachmentSecureURL')) {
128:                 $this->content = str_replace($attachmentURL, 'href="'.$this->BO->getAttachmentSecureURL($fileName).'" rel="nofollow"', $this->content);
129:             }
130:         }
131: 
132:         // Handle image attachments
133:         $attachments = array();
134:         preg_match_all('/\<img\ src\=\"\$attachURL\/.*\.[a-zA-Z]{3}\"[^<]*/', $this->content, $attachments);
135: 
136:         foreach ($attachments[0] as $attachmentURL) {
137:             preg_match('/\/.*\.[a-zA-Z]{3}/', $attachmentURL, $matches);
138:             $fileName = $matches[0];
139: 
140:             if ($config->get('cms.images.widget')) {
141:                 // get the details of the source image
142:                 $path = $this->BO->getAttachmentsLocation().$fileName;
143:                 $image_details = getimagesize($path);
144:                 $imgType = $image_details[2];
145:                 if ($imgType == 1) {
146:                     $type = 'gif';
147:                 } elseif ($imgType == 2) {
148:                     $type = 'jpg';
149:                 } elseif ($imgType == 3) {
150:                     $type = 'png';
151:                 }
152: 
153:                 $img = new Image($path, $image_details[0], $image_details[1], $type, 0.95, false, (boolean) $config->get('cms.images.widget.secure'));
154: 
155:                 $this->content = str_replace($attachmentURL, $img->renderHTMLLink(), $this->content);
156:             } else {
157:                 // render a normal image link to the ViewAttachment controller
158:                 if (method_exists($this->BO, 'getAttachmentSecureURL')) {
159:                     $this->content = str_replace($attachmentURL, '<img src="'.$this->BO->getAttachmentSecureURL($fileName).'">', $this->content);
160:                 }
161:             }
162:         }
163:     }
164: 
165:     /**
166:      * Facade method which will invoke our custom markdown class rather than the standard one.
167:      *
168:      * @return string
169:      *
170:      * @since 1.0
171:      */
172:     public function markdown($text)
173:     {
174:         $config = ConfigProvider::getInstance();
175: 
176:         // Initialize the parser and return the result of its transform method.
177:         static $parser;
178: 
179:         if (!isset($parser)) {
180:             $parser = new \Alpha\Util\Extension\Markdown();
181:         }
182: 
183:         /*
184:          * Replace all instances of $sysURL in the text with the app.url setting from config
185:          */
186:         $text = str_replace('$sysURL', $config->get('app.url'), $text);
187: 
188:         // transform text using parser.
189:         return $parser->transform($text);
190:     }
191: 
192:     /**
193:      * Getter for the content.
194:      *
195:      * @return string
196:      *
197:      * @since 1.0
198:      */
199:     public function getContent()
200:     {
201:         return $this->content;
202:     }
203: 
204:     /**
205:      * Saves the HTML generated by Markdown to the cache directory.
206:      *
207:      * @throws Alpha\Exception\AlphaException
208:      *
209:      * @since 1.0
210:      */
211:     private function cache()
212:     {
213:         // check to ensure that the article is not transient before caching it
214:         if (!$this->BO->isTransient() && $this->filename != '') {
215:             $fp = fopen($this->filename, 'w');
216:             if (!$fp) {
217:                 throw new AlphaException('Failed to open the cache file for writing, directory permissions my not be set correctly!');
218:             } else {
219:                 flock($fp, 2); // locks the file for writting
220:                 fwrite($fp, $this->content);
221:                 flock($fp, 3); // unlocks the file
222:                 fclose($fp); //closes the file
223:             }
224:         }
225:     }
226: 
227:     /**
228:      * Used to check the HTML cache for the BO cache file.
229:      *
230:      * @return bool
231:      *
232:      * @since 1.0
233:      */
234:     public function checkCache()
235:     {
236:         return file_exists($this->filename);
237:     }
238: 
239:     /**
240:      * Method to load the content of the cache file to the $content attribute of this object.
241:      *
242:      * @throws Alpha\Exception\AlphaException
243:      *
244:      * @since 1.0
245:      */
246:     public function loadCache()
247:     {
248:         $fp = fopen($this->filename, 'r');
249: 
250:         if (!$fp) {
251:             throw new AlphaException('Failed to open the cache file for reading, directory permissions my not be set correctly!');
252:         } else {
253:             $this->content = fread($fp, filesize($this->filename));
254:             fclose($fp); //closes the file
255:         }
256:     }
257: }
258: 
Alpha Framework 2.0.4 API Documentation API documentation generated by ApiGen 2.8.0