8 * This source file is subject to the new BSD license that is bundled
9 * with this package in the file LICENSE.txt.
10 * It is also available through the world-wide-web at this URL:
11 * http://framework.zend.com/license/new-bsd
12 * If you did not receive a copy of the license and are unable to
13 * obtain it through the world-wide-web, please send an email
14 * to license@zend.com so we can send you a copy immediately.
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
19 * @license http://framework.zend.com/license/new-bsd New BSD License
25 * @see Zend_Feed_Builder_Interface
27 require_once 'Zend/Feed/Builder/Interface.php';
30 * @see Zend_Feed_Builder_Header
32 require_once 'Zend/Feed/Builder/Header.php';
35 * @see Zend_Feed_Builder_Entry
37 require_once 'Zend/Feed/Builder/Entry.php';
41 * A simple implementation of Zend_Feed_Builder_Interface.
43 * Users are encouraged to make their own classes to implement Zend_Feed_Builder_Interface
47 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
48 * @license http://framework.zend.com/license/new-bsd New BSD License
50 class Zend_Feed_Builder
implements Zend_Feed_Builder_Interface
53 * The data of the feed
62 * @var $_header Zend_Feed_Builder_Header
67 * List of the entries of the feed
69 * @var $_entries array
71 private $_entries = array();
74 * Constructor. The $data array must conform to the following format:
77 * 'title' => 'title of the feed', //required
78 * 'link' => 'canonical url to the feed', //required
79 * 'lastUpdate' => 'timestamp of the update date', // optional
80 * 'published' => 'timestamp of the publication date', //optional
81 * 'charset' => 'charset', // required
82 * 'description' => 'short description of the feed', //optional
83 * 'author' => 'author/publisher of the feed', //optional
84 * 'email' => 'email of the author', //optional
85 * 'webmaster' => 'email address for person responsible for technical issues' // optional, ignored if atom is used
86 * 'copyright' => 'copyright notice', //optional
87 * 'image' => 'url to image', //optional
88 * 'generator' => 'generator', // optional
89 * 'language' => 'language the feed is written in', // optional
90 * 'ttl' => 'how long in minutes a feed can be cached before refreshing', // optional, ignored if atom is used
91 * 'rating' => 'The PICS rating for the channel.', // optional, ignored if atom is used
93 * 'domain' => 'domain of the cloud, e.g. rpc.sys.com' // required
94 * 'port' => 'port to connect to' // optional, default to 80
95 * 'path' => 'path of the cloud, e.g. /RPC2 //required
96 * 'registerProcedure' => 'procedure to call, e.g. myCloud.rssPleaseNotify' // required
97 * 'protocol' => 'protocol to use, e.g. soap or xml-rpc' // required
98 * ), a cloud to be notified of updates // optional, ignored if atom is used
99 * 'textInput' => array(
100 * 'title' => 'the label of the Submit button in the text input area' // required,
101 * 'description' => 'explains the text input area' // required
102 * 'name' => 'the name of the text object in the text input area' // required
103 * 'link' => 'the URL of the CGI script that processes text input requests' // required
104 * ) // a text input box that can be displayed with the feed // optional, ignored if atom is used
105 * 'skipHours' => array(
106 * 'hour in 24 format', // e.g 13 (1pm)
107 * // up to 24 rows whose value is a number between 0 and 23
108 * ) // Hint telling aggregators which hours they can skip // optional, ignored if atom is used
109 * 'skipDays ' => array(
110 * 'a day to skip', // e.g Monday
111 * // up to 7 rows whose value is a Monday, Tuesday, Wednesday, Thursday, Friday, Saturday or Sunday
112 * ) // Hint telling aggregators which days they can skip // optional, ignored if atom is used
114 * 'author' => 'Artist column' // optional, default to the main author value
116 * 'name' => 'name of the owner' // optional, default to main author value
117 * 'email' => 'email of the owner' // optional, default to main email value
118 * ) // Owner of the podcast // optional
119 * 'image' => 'album/podcast art' // optional, default to the main image value
120 * 'subtitle' => 'short description' // optional, default to the main description value
121 * 'summary' => 'longer description' // optional, default to the main description value
122 * 'block' => 'Prevent an episode from appearing (yes|no)' // optional
123 * 'category' => array(
124 * array('main' => 'main category', // required
125 * 'sub' => 'sub category' // optional
128 * ) // 'Category column and in iTunes Music Store Browse' // required
129 * 'explicit' => 'parental advisory graphic (yes|no|clean)' // optional
130 * 'keywords' => 'a comma separated list of 12 keywords maximum' // optional
131 * 'new-feed-url' => 'used to inform iTunes of new feed URL location' // optional
132 * ) // Itunes extension data // optional, ignored if atom is used
133 * 'entries' => array(
135 * 'title' => 'title of the feed entry', //required
136 * 'link' => 'url to a feed entry', //required
137 * 'description' => 'short version of a feed entry', // only text, no html, required
138 * 'guid' => 'id of the article, if not given link value will used', //optional
139 * 'content' => 'long version', // can contain html, optional
140 * 'lastUpdate' => 'timestamp of the publication date', // optional
141 * 'comments' => 'comments page of the feed entry', // optional
142 * 'commentRss' => 'the feed url of the associated comments', // optional
144 * 'title' => 'title of the original source' // required,
145 * 'url' => 'url of the original source' // required
146 * ) // original source of the feed entry // optional
147 * 'category' => array(
149 * 'term' => 'first category label' // required,
150 * 'scheme' => 'url that identifies a categorization scheme' // optional
153 * //data for the second category and so on
155 * ) // list of the attached categories // optional
156 * 'enclosure' => array(
158 * 'url' => 'url of the linked enclosure' // required
159 * 'type' => 'mime type of the enclosure' // optional
160 * 'length' => 'length of the linked content in octets' // optional
163 * //data for the second enclosure and so on
165 * ) // list of the enclosures of the feed entry // optional
168 * //data for the second entry and so on
177 public function __construct(array $data)
179 $this->_data
= $data;
180 $this->_createHeader($data);
181 if (isset($data['entries'])) {
182 $this->_createEntries($data['entries']);
187 * Returns an instance of Zend_Feed_Builder_Header
188 * describing the header of the feed
190 * @return Zend_Feed_Builder_Header
192 public function getHeader()
194 return $this->_header
;
198 * Returns an array of Zend_Feed_Builder_Entry instances
199 * describing the entries of the feed
201 * @return array of Zend_Feed_Builder_Entry
203 public function getEntries()
205 return $this->_entries
;
209 * Create the Zend_Feed_Builder_Header instance
212 * @throws Zend_Feed_Builder_Exception
215 protected function _createHeader(array $data)
217 $mandatories = array('title', 'link', 'charset');
218 foreach ($mandatories as $mandatory) {
219 if (!isset($data[$mandatory])) {
221 * @see Zend_Feed_Builder_Exception
223 require_once 'Zend/Feed/Builder/Exception.php';
224 throw new Zend_Feed_Builder_Exception("$mandatory key is missing");
227 $this->_header
= new Zend_Feed_Builder_Header($data['title'], $data['link'], $data['charset']);
228 if (isset($data['lastUpdate'])) {
229 $this->_header
->setLastUpdate($data['lastUpdate']);
231 if (isset($data['published'])) {
232 $this->_header
->setPublishedDate($data['published']);
234 if (isset($data['description'])) {
235 $this->_header
->setDescription($data['description']);
237 if (isset($data['author'])) {
238 $this->_header
->setAuthor($data['author']);
240 if (isset($data['email'])) {
241 $this->_header
->setEmail($data['email']);
243 if (isset($data['webmaster'])) {
244 $this->_header
->setWebmaster($data['webmaster']);
246 if (isset($data['copyright'])) {
247 $this->_header
->setCopyright($data['copyright']);
249 if (isset($data['image'])) {
250 $this->_header
->setImage($data['image']);
252 if (isset($data['generator'])) {
253 $this->_header
->setGenerator($data['generator']);
255 if (isset($data['language'])) {
256 $this->_header
->setLanguage($data['language']);
258 if (isset($data['ttl'])) {
259 $this->_header
->setTtl($data['ttl']);
261 if (isset($data['rating'])) {
262 $this->_header
->setRating($data['rating']);
264 if (isset($data['cloud'])) {
265 $mandatories = array('domain', 'path', 'registerProcedure', 'protocol');
266 foreach ($mandatories as $mandatory) {
267 if (!isset($data['cloud'][$mandatory])) {
269 * @see Zend_Feed_Builder_Exception
271 require_once 'Zend/Feed/Builder/Exception.php';
272 throw new Zend_Feed_Builder_Exception("you have to define $mandatory property of your cloud");
275 $uri_str = 'http://' . $data['cloud']['domain'] . $data['cloud']['path'];
276 $this->_header
->setCloud($uri_str, $data['cloud']['registerProcedure'], $data['cloud']['protocol']);
278 if (isset($data['textInput'])) {
279 $mandatories = array('title', 'description', 'name', 'link');
280 foreach ($mandatories as $mandatory) {
281 if (!isset($data['textInput'][$mandatory])) {
283 * @see Zend_Feed_Builder_Exception
285 require_once 'Zend/Feed/Builder/Exception.php';
286 throw new Zend_Feed_Builder_Exception("you have to define $mandatory property of your textInput");
289 $this->_header
->setTextInput($data['textInput']['title'],
290 $data['textInput']['description'],
291 $data['textInput']['name'],
292 $data['textInput']['link']);
294 if (isset($data['skipHours'])) {
295 $this->_header
->setSkipHours($data['skipHours']);
297 if (isset($data['skipDays'])) {
298 $this->_header
->setSkipDays($data['skipDays']);
300 if (isset($data['itunes'])) {
301 $itunes = new Zend_Feed_Builder_Header_Itunes($data['itunes']['category']);
302 if (isset($data['itunes']['author'])) {
303 $itunes->setAuthor($data['itunes']['author']);
305 if (isset($data['itunes']['owner'])) {
306 $name = isset($data['itunes']['owner']['name']) ?
$data['itunes']['owner']['name'] : '';
307 $email = isset($data['itunes']['owner']['email']) ?
$data['itunes']['owner']['email'] : '';
308 $itunes->setOwner($name, $email);
310 if (isset($data['itunes']['image'])) {
311 $itunes->setImage($data['itunes']['image']);
313 if (isset($data['itunes']['subtitle'])) {
314 $itunes->setSubtitle($data['itunes']['subtitle']);
316 if (isset($data['itunes']['summary'])) {
317 $itunes->setSummary($data['itunes']['summary']);
319 if (isset($data['itunes']['block'])) {
320 $itunes->setBlock($data['itunes']['block']);
322 if (isset($data['itunes']['explicit'])) {
323 $itunes->setExplicit($data['itunes']['explicit']);
325 if (isset($data['itunes']['keywords'])) {
326 $itunes->setKeywords($data['itunes']['keywords']);
328 if (isset($data['itunes']['new-feed-url'])) {
329 $itunes->setNewFeedUrl($data['itunes']['new-feed-url']);
332 $this->_header
->setITunes($itunes);
337 * Create the array of article entries
340 * @throws Zend_Feed_Builder_Exception
343 protected function _createEntries(array $data)
345 foreach ($data as $row) {
346 $mandatories = array('title', 'link', 'description');
347 foreach ($mandatories as $mandatory) {
348 if (!isset($row[$mandatory])) {
350 * @see Zend_Feed_Builder_Exception
352 require_once 'Zend/Feed/Builder/Exception.php';
353 throw new Zend_Feed_Builder_Exception("$mandatory key is missing");
356 $entry = new Zend_Feed_Builder_Entry($row['title'], $row['link'], $row['description']);
357 if (isset($row['author'])) {
358 $entry->setAuthor($row['author']);
360 if (isset($row['guid'])) {
361 $entry->setId($row['guid']);
363 if (isset($row['content'])) {
364 $entry->setContent($row['content']);
366 if (isset($row['lastUpdate'])) {
367 $entry->setLastUpdate($row['lastUpdate']);
369 if (isset($row['comments'])) {
370 $entry->setCommentsUrl($row['comments']);
372 if (isset($row['commentRss'])) {
373 $entry->setCommentsRssUrl($row['commentRss']);
375 if (isset($row['source'])) {
376 $mandatories = array('title', 'url');
377 foreach ($mandatories as $mandatory) {
378 if (!isset($row['source'][$mandatory])) {
380 * @see Zend_Feed_Builder_Exception
382 require_once 'Zend/Feed/Builder/Exception.php';
383 throw new Zend_Feed_Builder_Exception("$mandatory key of source property is missing");
386 $entry->setSource($row['source']['title'], $row['source']['url']);
388 if (isset($row['category'])) {
389 $entry->setCategories($row['category']);
391 if (isset($row['enclosure'])) {
392 $entry->setEnclosures($row['enclosure']);
395 $this->_entries
[] = $entry;