File indexing completed on 2025-01-19 05:21:07
0001 <?php 0002 0003 /** 0004 * Zend Framework 0005 * 0006 * LICENSE 0007 * 0008 * This source file is subject to the new BSD license that is bundled 0009 * with this package in the file LICENSE.txt. 0010 * It is also available through the world-wide-web at this URL: 0011 * http://framework.zend.com/license/new-bsd 0012 * If you did not receive a copy of the license and are unable to 0013 * obtain it through the world-wide-web, please send an email 0014 * to license@zend.com so we can send you a copy immediately. 0015 * 0016 * @category Zend 0017 * @package Zend_Feed 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 * @version $Id$ 0021 */ 0022 0023 0024 /** 0025 * @see Zend_Feed_Builder_Interface 0026 */ 0027 // require_once 'Zend/Feed/Builder/Interface.php'; 0028 0029 /** 0030 * @see Zend_Feed_Builder_Header 0031 */ 0032 // require_once 'Zend/Feed/Builder/Header.php'; 0033 0034 /** 0035 * @see Zend_Feed_Builder_Entry 0036 */ 0037 // require_once 'Zend/Feed/Builder/Entry.php'; 0038 0039 0040 /** 0041 * A simple implementation of Zend_Feed_Builder_Interface. 0042 * 0043 * Users are encouraged to make their own classes to implement Zend_Feed_Builder_Interface 0044 * 0045 * @category Zend 0046 * @package Zend_Feed 0047 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0048 * @license http://framework.zend.com/license/new-bsd New BSD License 0049 */ 0050 class Zend_Feed_Builder implements Zend_Feed_Builder_Interface 0051 { 0052 /** 0053 * The data of the feed 0054 * 0055 * @var $_data array 0056 */ 0057 private $_data; 0058 0059 /** 0060 * Header of the feed 0061 * 0062 * @var $_header Zend_Feed_Builder_Header 0063 */ 0064 private $_header; 0065 0066 /** 0067 * List of the entries of the feed 0068 * 0069 * @var $_entries array 0070 */ 0071 private $_entries = array(); 0072 0073 /** 0074 * Constructor. The $data array must conform to the following format: 0075 * <code> 0076 * array( 0077 * 'title' => 'title of the feed', //required 0078 * 'link' => 'canonical url to the feed', //required 0079 * 'lastUpdate' => 'timestamp of the update date', // optional 0080 * 'published' => 'timestamp of the publication date', //optional 0081 * 'charset' => 'charset', // required 0082 * 'description' => 'short description of the feed', //optional 0083 * 'author' => 'author/publisher of the feed', //optional 0084 * 'email' => 'email of the author', //optional 0085 * 'webmaster' => 'email address for person responsible for technical issues' // optional, ignored if atom is used 0086 * 'copyright' => 'copyright notice', //optional 0087 * 'image' => 'url to image', //optional 0088 * 'generator' => 'generator', // optional 0089 * 'language' => 'language the feed is written in', // optional 0090 * 'ttl' => 'how long in minutes a feed can be cached before refreshing', // optional, ignored if atom is used 0091 * 'rating' => 'The PICS rating for the channel.', // optional, ignored if atom is used 0092 * 'cloud' => array( 0093 * 'domain' => 'domain of the cloud, e.g. rpc.sys.com' // required 0094 * 'port' => 'port to connect to' // optional, default to 80 0095 * 'path' => 'path of the cloud, e.g. /RPC2 //required 0096 * 'registerProcedure' => 'procedure to call, e.g. myCloud.rssPleaseNotify' // required 0097 * 'protocol' => 'protocol to use, e.g. soap or xml-rpc' // required 0098 * ), a cloud to be notified of updates // optional, ignored if atom is used 0099 * 'textInput' => array( 0100 * 'title' => 'the label of the Submit button in the text input area' // required, 0101 * 'description' => 'explains the text input area' // required 0102 * 'name' => 'the name of the text object in the text input area' // required 0103 * 'link' => 'the URL of the CGI script that processes text input requests' // required 0104 * ) // a text input box that can be displayed with the feed // optional, ignored if atom is used 0105 * 'skipHours' => array( 0106 * 'hour in 24 format', // e.g 13 (1pm) 0107 * // up to 24 rows whose value is a number between 0 and 23 0108 * ) // Hint telling aggregators which hours they can skip // optional, ignored if atom is used 0109 * 'skipDays ' => array( 0110 * 'a day to skip', // e.g Monday 0111 * // up to 7 rows whose value is a Monday, Tuesday, Wednesday, Thursday, Friday, Saturday or Sunday 0112 * ) // Hint telling aggregators which days they can skip // optional, ignored if atom is used 0113 * 'itunes' => array( 0114 * 'author' => 'Artist column' // optional, default to the main author value 0115 * 'owner' => array( 0116 * 'name' => 'name of the owner' // optional, default to main author value 0117 * 'email' => 'email of the owner' // optional, default to main email value 0118 * ) // Owner of the podcast // optional 0119 * 'image' => 'album/podcast art' // optional, default to the main image value 0120 * 'subtitle' => 'short description' // optional, default to the main description value 0121 * 'summary' => 'longer description' // optional, default to the main description value 0122 * 'block' => 'Prevent an episode from appearing (yes|no)' // optional 0123 * 'category' => array( 0124 * array('main' => 'main category', // required 0125 * 'sub' => 'sub category' // optional 0126 * ), 0127 * // up to 3 rows 0128 * ) // 'Category column and in iTunes Music Store Browse' // required 0129 * 'explicit' => 'parental advisory graphic (yes|no|clean)' // optional 0130 * 'keywords' => 'a comma separated list of 12 keywords maximum' // optional 0131 * 'new-feed-url' => 'used to inform iTunes of new feed URL location' // optional 0132 * ) // Itunes extension data // optional, ignored if atom is used 0133 * 'entries' => array( 0134 * array( 0135 * 'title' => 'title of the feed entry', //required 0136 * 'link' => 'url to a feed entry', //required 0137 * 'description' => 'short version of a feed entry', // only text, no html, required 0138 * 'guid' => 'id of the article, if not given link value will used', //optional 0139 * 'content' => 'long version', // can contain html, optional 0140 * 'lastUpdate' => 'timestamp of the publication date', // optional 0141 * 'comments' => 'comments page of the feed entry', // optional 0142 * 'commentRss' => 'the feed url of the associated comments', // optional 0143 * 'source' => array( 0144 * 'title' => 'title of the original source' // required, 0145 * 'url' => 'url of the original source' // required 0146 * ) // original source of the feed entry // optional 0147 * 'category' => array( 0148 * array( 0149 * 'term' => 'first category label' // required, 0150 * 'scheme' => 'url that identifies a categorization scheme' // optional 0151 * ), 0152 * array( 0153 * //data for the second category and so on 0154 * ) 0155 * ) // list of the attached categories // optional 0156 * 'enclosure' => array( 0157 * array( 0158 * 'url' => 'url of the linked enclosure' // required 0159 * 'type' => 'mime type of the enclosure' // optional 0160 * 'length' => 'length of the linked content in octets' // optional 0161 * ), 0162 * array( 0163 * //data for the second enclosure and so on 0164 * ) 0165 * ) // list of the enclosures of the feed entry // optional 0166 * ), 0167 * array( 0168 * //data for the second entry and so on 0169 * ) 0170 * ) 0171 * ); 0172 * </code> 0173 * 0174 * @param array $data 0175 * @return void 0176 */ 0177 public function __construct(array $data) 0178 { 0179 $this->_data = $data; 0180 $this->_createHeader($data); 0181 if (isset($data['entries'])) { 0182 $this->_createEntries($data['entries']); 0183 } 0184 } 0185 0186 /** 0187 * Returns an instance of Zend_Feed_Builder_Header 0188 * describing the header of the feed 0189 * 0190 * @return Zend_Feed_Builder_Header 0191 */ 0192 public function getHeader() 0193 { 0194 return $this->_header; 0195 } 0196 0197 /** 0198 * Returns an array of Zend_Feed_Builder_Entry instances 0199 * describing the entries of the feed 0200 * 0201 * @return array of Zend_Feed_Builder_Entry 0202 */ 0203 public function getEntries() 0204 { 0205 return $this->_entries; 0206 } 0207 0208 /** 0209 * Create the Zend_Feed_Builder_Header instance 0210 * 0211 * @param array $data 0212 * @throws Zend_Feed_Builder_Exception 0213 * @return void 0214 */ 0215 protected function _createHeader(array $data) 0216 { 0217 $mandatories = array('title', 'link', 'charset'); 0218 foreach ($mandatories as $mandatory) { 0219 if (!isset($data[$mandatory])) { 0220 /** 0221 * @see Zend_Feed_Builder_Exception 0222 */ 0223 // require_once 'Zend/Feed/Builder/Exception.php'; 0224 throw new Zend_Feed_Builder_Exception("$mandatory key is missing"); 0225 } 0226 } 0227 $this->_header = new Zend_Feed_Builder_Header($data['title'], $data['link'], $data['charset']); 0228 if (isset($data['lastUpdate'])) { 0229 $this->_header->setLastUpdate($data['lastUpdate']); 0230 } 0231 if (isset($data['published'])) { 0232 $this->_header->setPublishedDate($data['published']); 0233 } 0234 if (isset($data['description'])) { 0235 $this->_header->setDescription($data['description']); 0236 } 0237 if (isset($data['author'])) { 0238 $this->_header->setAuthor($data['author']); 0239 } 0240 if (isset($data['email'])) { 0241 $this->_header->setEmail($data['email']); 0242 } 0243 if (isset($data['webmaster'])) { 0244 $this->_header->setWebmaster($data['webmaster']); 0245 } 0246 if (isset($data['copyright'])) { 0247 $this->_header->setCopyright($data['copyright']); 0248 } 0249 if (isset($data['image'])) { 0250 $this->_header->setImage($data['image']); 0251 } 0252 if (isset($data['generator'])) { 0253 $this->_header->setGenerator($data['generator']); 0254 } 0255 if (isset($data['language'])) { 0256 $this->_header->setLanguage($data['language']); 0257 } 0258 if (isset($data['ttl'])) { 0259 $this->_header->setTtl($data['ttl']); 0260 } 0261 if (isset($data['rating'])) { 0262 $this->_header->setRating($data['rating']); 0263 } 0264 if (isset($data['cloud'])) { 0265 $mandatories = array('domain', 'path', 'registerProcedure', 'protocol'); 0266 foreach ($mandatories as $mandatory) { 0267 if (!isset($data['cloud'][$mandatory])) { 0268 /** 0269 * @see Zend_Feed_Builder_Exception 0270 */ 0271 // require_once 'Zend/Feed/Builder/Exception.php'; 0272 throw new Zend_Feed_Builder_Exception("you have to define $mandatory property of your cloud"); 0273 } 0274 } 0275 $uri_str = 'http://' . $data['cloud']['domain'] . $data['cloud']['path']; 0276 $this->_header->setCloud($uri_str, $data['cloud']['registerProcedure'], $data['cloud']['protocol']); 0277 } 0278 if (isset($data['textInput'])) { 0279 $mandatories = array('title', 'description', 'name', 'link'); 0280 foreach ($mandatories as $mandatory) { 0281 if (!isset($data['textInput'][$mandatory])) { 0282 /** 0283 * @see Zend_Feed_Builder_Exception 0284 */ 0285 // require_once 'Zend/Feed/Builder/Exception.php'; 0286 throw new Zend_Feed_Builder_Exception("you have to define $mandatory property of your textInput"); 0287 } 0288 } 0289 $this->_header->setTextInput($data['textInput']['title'], 0290 $data['textInput']['description'], 0291 $data['textInput']['name'], 0292 $data['textInput']['link']); 0293 } 0294 if (isset($data['skipHours'])) { 0295 $this->_header->setSkipHours($data['skipHours']); 0296 } 0297 if (isset($data['skipDays'])) { 0298 $this->_header->setSkipDays($data['skipDays']); 0299 } 0300 if (isset($data['itunes'])) { 0301 $itunes = new Zend_Feed_Builder_Header_Itunes($data['itunes']['category']); 0302 if (isset($data['itunes']['author'])) { 0303 $itunes->setAuthor($data['itunes']['author']); 0304 } 0305 if (isset($data['itunes']['owner'])) { 0306 $name = isset($data['itunes']['owner']['name']) ? $data['itunes']['owner']['name'] : ''; 0307 $email = isset($data['itunes']['owner']['email']) ? $data['itunes']['owner']['email'] : ''; 0308 $itunes->setOwner($name, $email); 0309 } 0310 if (isset($data['itunes']['image'])) { 0311 $itunes->setImage($data['itunes']['image']); 0312 } 0313 if (isset($data['itunes']['subtitle'])) { 0314 $itunes->setSubtitle($data['itunes']['subtitle']); 0315 } 0316 if (isset($data['itunes']['summary'])) { 0317 $itunes->setSummary($data['itunes']['summary']); 0318 } 0319 if (isset($data['itunes']['block'])) { 0320 $itunes->setBlock($data['itunes']['block']); 0321 } 0322 if (isset($data['itunes']['explicit'])) { 0323 $itunes->setExplicit($data['itunes']['explicit']); 0324 } 0325 if (isset($data['itunes']['keywords'])) { 0326 $itunes->setKeywords($data['itunes']['keywords']); 0327 } 0328 if (isset($data['itunes']['new-feed-url'])) { 0329 $itunes->setNewFeedUrl($data['itunes']['new-feed-url']); 0330 } 0331 0332 $this->_header->setITunes($itunes); 0333 } 0334 } 0335 0336 /** 0337 * Create the array of article entries 0338 * 0339 * @param array $data 0340 * @throws Zend_Feed_Builder_Exception 0341 * @return void 0342 */ 0343 protected function _createEntries(array $data) 0344 { 0345 foreach ($data as $row) { 0346 $mandatories = array('title', 'link', 'description'); 0347 foreach ($mandatories as $mandatory) { 0348 if (!isset($row[$mandatory])) { 0349 /** 0350 * @see Zend_Feed_Builder_Exception 0351 */ 0352 // require_once 'Zend/Feed/Builder/Exception.php'; 0353 throw new Zend_Feed_Builder_Exception("$mandatory key is missing"); 0354 } 0355 } 0356 $entry = new Zend_Feed_Builder_Entry($row['title'], $row['link'], $row['description']); 0357 if (isset($row['author'])) { 0358 $entry->setAuthor($row['author']); 0359 } 0360 if (isset($row['guid'])) { 0361 $entry->setId($row['guid']); 0362 } 0363 if (isset($row['content'])) { 0364 $entry->setContent($row['content']); 0365 } 0366 if (isset($row['lastUpdate'])) { 0367 $entry->setLastUpdate($row['lastUpdate']); 0368 } 0369 if (isset($row['comments'])) { 0370 $entry->setCommentsUrl($row['comments']); 0371 } 0372 if (isset($row['commentRss'])) { 0373 $entry->setCommentsRssUrl($row['commentRss']); 0374 } 0375 if (isset($row['source'])) { 0376 $mandatories = array('title', 'url'); 0377 foreach ($mandatories as $mandatory) { 0378 if (!isset($row['source'][$mandatory])) { 0379 /** 0380 * @see Zend_Feed_Builder_Exception 0381 */ 0382 // require_once 'Zend/Feed/Builder/Exception.php'; 0383 throw new Zend_Feed_Builder_Exception("$mandatory key of source property is missing"); 0384 } 0385 } 0386 $entry->setSource($row['source']['title'], $row['source']['url']); 0387 } 0388 if (isset($row['category'])) { 0389 $entry->setCategories($row['category']); 0390 } 0391 if (isset($row['enclosure'])) { 0392 $entry->setEnclosures($row['enclosure']); 0393 } 0394 0395 $this->_entries[] = $entry; 0396 } 0397 } 0398 }