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

  • AlphaFeed
  • Atom
  • RSS
  • RSS2
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * Base feed class for generating syndication feeds
  5:  * 
  6:  * @package alpha::util::feeds
  7:  * @since 1.0
  8:  * @author John Collins <dev@alphaframework.org>
  9:  * @version $Id: AlphaFeed.inc 1624 2012-12-21 12:17:55Z alphadevx $
 10:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
 11:  * @copyright Copyright (c) 2012, John Collins (founder of Alpha Framework).  
 12:  * All rights reserved.
 13:  * 
 14:  * <pre>
 15:  * Redistribution and use in source and binary forms, with or 
 16:  * without modification, are permitted provided that the 
 17:  * following conditions are met:
 18:  * 
 19:  * * Redistributions of source code must retain the above 
 20:  *   copyright notice, this list of conditions and the 
 21:  *   following disclaimer.
 22:  * * Redistributions in binary form must reproduce the above 
 23:  *   copyright notice, this list of conditions and the 
 24:  *   following disclaimer in the documentation and/or other 
 25:  *   materials provided with the distribution.
 26:  * * Neither the name of the Alpha Framework nor the names 
 27:  *   of its contributors may be used to endorse or promote 
 28:  *   products derived from this software without specific 
 29:  *   prior written permission.
 30:  *   
 31:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
 32:  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
 33:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 34:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 35:  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
 36:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 37:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
 38:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 39:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 40:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 41:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 42:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 43:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 44:  * </pre>
 45:  *  
 46:  */
 47: abstract class AlphaFeed {
 48:     /**
 49:      * The DOMDocument object used to create the feed
 50:      * 
 51:      * @var DOMDocument
 52:      * @since 1.0
 53:      */
 54:     protected $rssDoc;
 55:     
 56:     /**
 57:      * The DOMElement object used to hold the item or entry elements
 58:      * 
 59:      * @var DOMElement
 60:      * @since 1.0
 61:      */
 62:     protected $docElement;
 63:     
 64:     /**
 65:      * Holds the DOMElement to which metadata is added for the feed
 66:      * 
 67:      * @var DOMElement
 68:      * @since 1.0
 69:      */
 70:     protected $root;
 71:     
 72:     /**
 73:      * The actual root tag used in each feed type
 74:      * 
 75:      * @var string
 76:      * @since 1.0
 77:      */
 78:     protected $rootTag;
 79:     
 80:     /**
 81:      * An array of feed items
 82:      * 
 83:      * @var array
 84:      * @since 1.0
 85:      */
 86:     protected $items;
 87:     
 88:     /**
 89:      * If the feed format has a channel or not
 90:      * 
 91:      * @var boolean
 92:      * @since 1.0
 93:      */
 94:     protected $hasChannel = true;
 95:     
 96:     /**
 97:      * Maps the tags to the feed-specific tags
 98:      * 
 99:      * @var array
100:      * @since 1.0
101:      */
102:     protected $tagMap = array('item'=>'item','feeddesc'=>'description','itemdesc'=>'description');
103:     
104:     /**
105:      * The BO which we will serve up in this feed
106:      * 
107:      * @var AlphaDAO
108:      * @since 1.0
109:      */
110:     private $BO;
111:     
112:     /**
113:      * An array containing BO field names -> RSS field name mappings
114:      * 
115:      * @var array
116:      * @since 1.0
117:      */
118:     protected $fieldNameMappings;
119:     
120:     /**
121:      * The XML namespace to use in the generated feed
122:      * 
123:      * @var string
124:      */
125:     protected $nameSpace;
126:     
127:     /**
128:      * Trace logger
129:      * 
130:      * @var Logger
131:      * @since 1.0
132:      */
133:     private static $logger = null;      
134:     
135:     /**
136:      * The constructor
137:      * 
138:      * @param string $BOName The classname of the BO to render a feed for.
139:      * @param string $title The title of the feed.
140:      * @param string $url The base URL for the feed.
141:      * @param string $description The description of the feed.
142:      * @param string $pubDate The publish date, only used in Atom feeds.
143:      * @param integer $id The feed id, only used in Atom feeds.
144:      * @param integer $limit The amount of items to render in the feed.
145:      * @throws IllegalArguementException
146:      * @since 1.0
147:      */
148:     public function __construct($BOName, $title, $url, $description, $pubDate = null, $id = null, $limit = 10) {
149:         self::$logger = new Logger('AlphaFeed');
150:         self::$logger->debug('>>__construct(BOName=['.$BOName.'], title=['.$title.'], url=['.$url.'], description=['.$description.'], pubDate=['.$pubDate.'], id=['.$id.'], limit=['.$limit.'])');
151:         
152:         $this->rssDoc = new DOMDocument();
153:         $this->rssDoc->loadXML($this->rootTag);
154:         $this->docElement = $this->rssDoc->documentElement;
155:         
156:         try {
157:             AlphaDAO::loadClassDef($BOName);
158:             $this->BO = new $BOName;
159:         }catch (IllegalArguementException $e) {
160:             self::$logger->error('Unable to load the class definition for the class ['.$BOName.'] while trying to generate a feed!');
161:             throw $e;
162:         }                   
163:         
164:         if ($this->hasChannel) {
165:             $root = $this->createFeedElement('channel');
166:             $this->root = $this->docElement->appendChild($root);
167:         }else{
168:             $this->root = $this->docElement;
169:         }
170:         
171:         $this->createRSSNode('feed', $this->root, $title, $url, $description, $pubDate, $id);
172:         
173:         self::$logger->debug('<<__construct');
174:     }
175:     
176:     /**
177:      * Method to load all of the BO items to the feed from the database, from the newest to the 
178:      * $limit provided 
179:      * 
180:      * @param integer $limit The amount of items to render in the feed.
181:      * @param string $sortBy The name of the field to sort the feed by.
182:      * @since 1.0
183:      */
184:     public function loadBOs($limit, $sortBy) {      
185:         
186:         $BOs = $this->BO->loadAll(0, $limit, $sortBy, 'DESC');
187:         
188:         AlphaDAO::disconnect();
189:         
190:         foreach($BOs as $BO) {
191:             $this->addBO($BO);
192:         }
193:     }
194:     
195:     /**
196:      * Method for adding a BO to the current feed 
197:      * 
198:      * @param AlphaDAO $BO
199:      */
200:     public function addBO($BO) {
201:         $title = $BO->get($this->fieldNameMappings['title']);           
202:         $url = $BO->get($this->fieldNameMappings['url']);
203:             
204:         if(isset($this->fieldNameMappings['description'])) {
205:             $description = $BO->get($this->fieldNameMappings['description']);
206:         }else{
207:             $description = '';
208:         }
209:             
210:         if(isset($this->fieldNameMappings['pubDate'])) {
211:             $dateTS = strtotime($BO->get($this->fieldNameMappings['pubDate']));
212:             $pubDate = date(DATE_ATOM, $dateTS);
213:         }else{
214:             $pubDate = '';
215:         }
216:             
217:         if(isset($this->fieldNameMappings['id']))
218:             $id = $BO->get($this->fieldNameMappings['id']);
219:         else
220:             $id = '';
221:             
222:         $this->addItem($title, $url, $description, $pubDate, $id);
223:     }
224:     
225:     /**
226:      * Method for mapping BO fieldnames to feed field names
227:      * 
228:      * @param string $title The title of the feed.
229:      * @param string $url The base URL for the feed.
230:      * @param string $description The description of the feed.
231:      * @param string $pubDate The publish date, only used in Atom feeds.
232:      * @param integer $id The feed id, only used in Atom feeds.
233:      * @since 1.0
234:      */
235:     public function setFieldMappings($title, $url, $description=null, $pubDate=null, $id=null) {
236:         $this->fieldNameMappings = array(
237:             'title' => $title,
238:             'url' => $url           
239:         );
240:         
241:         if(isset($description))
242:             $this->fieldNameMappings['description'] = $description;
243:             
244:         if(isset($pubDate))
245:             $this->fieldNameMappings['pubDate'] = $pubDate;
246:             
247:         if(isset($id))
248:             $this->fieldNameMappings['id'] = $id;
249:     }
250:     
251:     /**
252:      * Method for creating a new feed element
253:      * 
254:      * @param string $name The name of the element.
255:      * @param string $value The value of the element.
256:      * @return DOMElement
257:      * @since 1.0
258:      */
259:     protected function createFeedElement($name, $value=null) {
260:         $value = htmlspecialchars($value);
261:         
262:         if($this->nameSpace == null) {          
263:             return $this->rssDoc->createElement($name, $value);
264:         }else{
265:             return $this->rssDoc->createElementNS($this->nameSpace, $name, $value);
266:         }
267:     }
268:     
269:     /**
270:      * Method for creating link elements (note that Atom has a different format)
271:      * 
272:      * @param DOMElement $parent The parent element.
273:      * @param string $url The URL for the link.
274:      * @since 1.0
275:      */
276:     protected function createLink($parent, $url) {
277:         $link = $this->createFeedElement('link', $url);
278:         $parent->appendChild($link);
279:     }
280:     
281:     /**
282:      * Method for creating an RSS node with a title, url and description
283:      * 
284:      * @param integer $type Can be either (item|feed) to indicate the type of node we are creating.
285:      * @param DOMElement $parent The parent element.
286:      * @param string $title The title of the feed.
287:      * @param string $url The base URL for the feed.
288:      * @param string $description The description of the feed.
289:      * @param string $pubDate The publish date, only used in Atom feeds.
290:      * @param integer $id The feed id, only used in Atom feeds.
291:      * @since 1.0
292:      * @throws IllegalArguementException
293:      */
294:     protected function createRSSNode($type, $parent, $title, $url, $description, $pubDate=null, $id = null) {
295:         $this->createLink($parent, $url);       
296:         $title = $this->createFeedElement('title', $title);     
297:         $parent->appendChild($title);
298:         
299:         if ($type == 'item') {
300:             $titletag = $this->tagMap['itemdesc'];
301:         }else if ($type == 'feed') {
302:             $titletag = $this->tagMap['feeddesc'];
303:         }else{
304:             throw new IllegalArguementException('The type paramater ['.$type.'] provided is invalid!');
305:         }
306:         
307:         $description = $this->createFeedElement($titletag, $description);
308:         $parent->appendChild($description);
309:         
310:         // id elements and updated elements are just for Atom!
311:         if ($id != null) {
312:             $idnode = $this->createFeedElement('id', $id);
313:             $parent->appendChild($idnode);
314:         }
315:         
316:         if ($pubDate != null) {
317:             $datenode = $this->createFeedElement('updated', $pubDate);
318:             $parent->appendChild($datenode);
319:         }
320:     }
321:     
322:     /**
323:      * Method for adding an item to a feed
324:      * 
325:      * @param string $title The title of the feed.
326:      * @param string $url The base URL for the feed.
327:      * @param string $description The description of the feed.
328:      * @param string $pubDate The publish date, only used in Atom feeds.
329:      * @param integer $id The feed id, only used in Atom feeds.
330:      * @since 1.0
331:      */
332:     protected function addItem($title, $url, $description=null, $pubDate=null, $id=null) {      
333:         $item = $this->createFeedElement($this->tagMap['item']);
334:         
335:         if ($this->docElement->appendChild($item)) {            
336:             $this->createRSSNode('item', $item, $title, $url, $description, $pubDate, $id);
337:         }
338:     }
339:     
340:     /**
341:      * Returns the formatted XML for the feed as a string
342:      * 
343:      * @return string
344:      * @since 1.0
345:      */
346:     public function render() {
347:         if ($this->rssDoc) {
348:             $this->rssDoc->formatOutput = true;
349:             return $this->rssDoc->saveXML();
350:         }else{
351:             return '';
352:         }
353:     }
354: }
355: 
356: ?>
Alpha Framework ${alpha.version.new} API Documentation API documentation generated by ApiGen 2.8.0