PluginProbe
FeedWordPress / 2011.0721
FeedWordPress v2011.0721
trunk 0.8 0.9 0.91 0.95 0.96 0.97 0.98 0.981 0.99 0.991 0.992 0.993 2008.1030 2008.1101 2008.1105 2008.1214 2009.0612 2009.0613 2009.0618 2009.0707 2009.1111 2009.1112 2010.0127 2010.0528 All 65 releases
feedwordpress / magpiefromsimplepie.class.php

magpiefromsimplepie.class.php in FeedWordPress 2011.0721, at magpiefromsimplepie.class.php

815 lines 26.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 require_once(dirname(__FILE__).'/feedtime.class.php');
3
4 /**
5 * class MagpieFromSimplePie: compatibility layer to prevent existing filters
6 * from breaking.
7 *
8 * @since 2010.0203
9 * @version 2010.0612
10 */
11
12 class MagpieFromSimplePie {
13 var $pie;
14 var $originals;
15
16 var $channel;
17 var $items;
18 var $textinput = array ();
19 var $image = array();
20
21 var $feed_type;
22 var $feed_version;
23
24 var $_XMLNS_FAMILIAR = array (
25 'http://www.w3.org/2005/Atom' => 'atom' /* 1.0 */,
26 'http://purl.org/atom/ns#' => 'atom' /* pre-1.0 */,
27 'http://purl.org/rss/1.0/' => 'rss' /* 1.0 */,
28 'http://backend.userland.com/RSS2' => 'rss' /* 2.0 */,
29 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' => 'rdf',
30 'http://www.w3.org/1999/xhtml' => 'xhtml',
31 'http://purl.org/dc/elements/1.1/' => 'dc',
32 'http://purl.org/dc/terms/' => 'dcterms',
33 'http://purl.org/rss/1.0/modules/content/' => 'content',
34 'http://purl.org/rss/1.0/modules/syndication/' => 'sy',
35 'http://purl.org/rss/1.0/modules/taxonomy/' => 'taxo',
36 'http://purl.org/rss/1.0/modules/dc/' => 'dc',
37 'http://wellformedweb.org/CommentAPI/' => 'wfw',
38 'http://webns.net/mvcb/' => 'admin',
39 'http://purl.org/rss/1.0/modules/annotate/' => 'annotate',
40 'http://xmlns.com/foaf/0.1/' => 'foaf',
41 'http://madskills.com/public/xml/rss/module/trackback/' => 'trackback',
42 'http://web.resource.org/cc/' => 'cc',
43 'http://search.yahoo.com/mrss' => 'media',
44 'http://search.yahoo.com/mrss/' => 'media',
45 'http://video.search.yahoo.com/mrss' => 'media',
46 'http://video.search.yahoo.com/mrss/' => 'media',
47 'http://purl.org/syndication/thread/1.0' => 'thr',
48 'http://purl.org/syndication/thread/1.0/' => 'thr',
49 'http://www.w3.org/XML/1998/namespace' => 'xml',
50 'http://www.itunes.com/dtds/podcast-1.0.dtd' => 'itunes',
51 'http://a9.com/-/spec/opensearchrss/1.0/' => 'openSearch',
52 'http://purl.org/rss/1.0/modules/slash/' => 'slash',
53 'http://www.google.com/schemas/reader/atom/' => 'gr',
54 'urn:atom-extension:indexing' => 'indexing',
55 );
56
57 /**
58 * MagpieFromSimplePie constructor
59 *
60 * @param SimplePie $pie The feed to convert to MagpieRSS format.
61 * @param mixed $item
62 *
63 * @uses SimplePie::get_items
64 * @uses MagpieFromSimplePie::processFeedData
65 * @uses MagpieFromSimplePie::processItemData
66 * @uses MagpieFromSimplePie::normalize
67 * @uses MagpieFromSimplePie::is_atom
68 */
69 function MagpieFromSimplePie ($pie, $item = true) {
70 $this->pie = $pie;
71
72 // item in {NULL, true} = process channel data
73 if (!is_a($item, 'SimplePie_Item')) :
74 $this->originals = $this->pie->get_items();
75
76 $this->channel = $this->processFeedData($this->pie->data);
77 else :
78 $this->originals = array($item);
79 $this->channel = NULL;
80 endif;
81
82 // item in {true, SimplePie_Item} = process item data
83 if (!is_null($item)) :
84 foreach ($this->originals as $key => $item) :
85 $this->items[$key] = $this->processItemData($item->data);
86 endforeach;
87 else :
88 $this->items = NULL;
89 endif;
90
91 $this->normalize();
92
93 // In case anyone goes poking around our private members (uh...)
94 $this->feed_type = ($this->is_atom() ? 'Atom' : 'RSS');
95 $this->feed_version = $this->feed_version();
96 $this->encoding = $pie->get_encoding();
97 } /* MagpieFromSimplePie constructor */
98
99 /**
100 * MagpieFromSimplePie::get_items: returns an array of MagpieRSS format arrays
101 * equivalent to the SimplePie_Item objects in the SimplePie object from which this
102 * object was constructed.
103 *
104 * @return array An array of MagpieRSS-format arrays representing the items on this feed
105 */
106 function get_items () {
107 return $this->items;
108 } /* MagpieFromSimplePie::get_items () */
109
110 /**
111 * MagpieFromSimplePie::get_item: returns a single MagpieRSS format array equivalent
112 * to a SimplePie_Item object from which this object was constructed.
113 *
114 * @return array A MagpieRSS-format array representing an item on this feed
115 */
116 function get_item () {
117 if (is_array($this->items)) :
118 $ret = reset($this->items);
119 else :
120 $ret = NULL;
121 endif;
122 return $ret;
123 } /* MagpieFromSimplePie::get_item () */
124
125 /**
126 * MagpieFromSimplePie::processFeedData
127 *
128 * @param array $data
129 * @return array
130 *
131 * @uses MagpieFromSimplePie::processChannelData()
132 */
133 function processFeedData ($data) {
134 $ret = array();
135 if (isset($data['child'])) : foreach ($data['child'] as $ns => $elements) :
136 foreach ($elements as $name => $multi) :
137 foreach ($multi as $element) :
138 if ($name=='feed' or $name=='channel') :
139 // Don't need to process these
140 foreach (array(
141 '',
142 'http://www.w3.org/2005/Atom',
143 'http://purl.org/rss/1.0/',
144 'http://backend.userland.com/RSS2'
145 ) as $ns) :
146 if (isset($element['child'][$ns]['entry'])) : unset($element['child'][$ns]['entry']); endif;
147 if (isset($element['child'][$ns]['item'])) : unset($element['child'][$ns]['item']); endif;
148 endforeach;
149
150 $ret = $this->processChannelData($element) + $ret;
151 elseif (in_array(strtolower($name), array('rss', 'rdf'))) :
152 // Drop down to get to <channel> element
153 $ret = $this->processFeedData($element) + $ret;
154 endif;
155 endforeach;
156 endforeach;
157 endforeach; endif;
158 return $ret;
159 } /* MagpieFromSimplePie::processFeedData() */
160
161 /**
162 * MagpieFromSimplePie::processChannelData
163 *
164 * @param array $data
165 * @param array $path
166 * @return array
167 *
168 * @uses MagpieFromSimplePie::handleAttributes
169 * @uses MagpieFromSimplePie::handleChildren
170 */
171 function processChannelData ($data, $path = array()) {
172 $ret = array();
173 $tagPath = strtolower(implode('_', $path));
174
175 // Only process at the right level
176 if (strlen($tagPath) > 0
177 and isset($data['data'])
178 and strlen($data['data']) > 0) :
179 $ret[$tagPath] = $data['data'];
180 endif;
181
182 $ret = $this->handleAttributes($data, $path)
183 + $this->handleChildren($data, $path, 'processChannelData')
184 + $ret;
185
186 return $ret;
187 } /* MagpieFromSimplePie::processChannelData() */
188
189 /**
190 * MagpieFromSimplePie::processItemData
191 *
192 * @param array $data
193 * @param array $path
194 * @return array
195 *
196 * @uses MagpieFromSimplePie::handleAttributes
197 * @uses MagpieFromSimplePie::handleChildren
198 */
199 function processItemData ($data, $path = array()) {
200 $ret = array();
201 $tagPath = strtolower(implode('_', $path));
202
203 if (strlen($tagPath) > 0 and isset($data['data']) and strlen($data['data']) > 0) :
204 $ret[$tagPath] = $data['data'];
205 endif;
206
207 // Set up xml:base to be recorded in array
208 if (isset($data['xml_base_explicit']) and $data['xml_base_explicit']) :
209 $data['attribs']['']['xml:base'] = $data['xml_base'];
210 endif;
211
212 $ret = $this->handleAttributes($data, $path)
213 + $this->handleChildren($data, $path, 'processItemData')
214 + $ret;
215
216 return $ret;
217 } /* MagpieFromSimplePie::processItemData() */
218
219 /**
220 * MagpieFromSimplePie::handleAttributes
221 *
222 * @param array $data
223 * @param array $path
224 * @return array
225 */
226 function handleAttributes ($data, $path) {
227 $tagPath = strtolower(implode('_', $path));
228 $ret = array();
229 if (isset($data['attribs'])) : foreach ($data['attribs'] as $ns => $pairs) :
230 if (isset($this->_XMLNS_FAMILIAR[$ns])) :
231 $ns = $this->_XMLNS_FAMILIAR[$ns];
232 endif;
233
234 foreach ($pairs as $attr => $value) :
235 $attr = strtolower($attr);
236 if ($ns=='rdf' and $attr=='about') :
237 $ret['about'] = $value;
238 elseif (strlen($tagPath) > 0) :
239 if (strlen($ns) > 0 and $this->is_namespaced($ns, /*attrib=*/ true)) :
240 $attr = $ns.':'.$attr;
241 endif;
242
243 $ret[$tagPath.'@'.$attr] = $value;
244 if (isset($ret[$tagPath.'@']) and strlen($ret[$tagPath.'@'])>0) :
245 $ret[$tagPath.'@'] .= ',';
246 else :
247 $ret[$tagPath.'@'] = '';
248 endif;
249 $ret[$tagPath.'@'] .= $attr;
250 endif;
251 endforeach;
252 endforeach; endif;
253 return $ret;
254 } /* MagpieFromSimplePie::handleAttributes() */
255
256 var $inImage = false;
257 var $inTextInput = false;
258
259 /**
260 * MagpieFromSimplePie::handleChildren
261 *
262 * @param array $data
263 * @param array $path
264 * @return array
265 *
266 * @uses MagpieFromSimplePie::get_attrib
267 * @uses MagpieFromSimplePie::is_atom
268 * @uses MagpieFromSimplePie::increment_element
269 * @uses MagpieFromSimplePie::processItemData
270 */
271 function handleChildren ($data, $path = array(), $method = 'processItemData') {
272 $tagPath = strtolower(implode('_', $path));
273 $ret = array();
274 if (isset($data['child'])) : foreach ($data['child'] as $ns => $elements) :
275 if (isset($this->_XMLNS_FAMILIAR[$ns])) :
276 $ns = $this->_XMLNS_FAMILIAR[$ns];
277 endif;
278 if (''==$ns) :
279 $ns = ($this->is_atom() ? 'atom' : 'rss');
280 endif;
281
282 foreach ($elements as $tag => $multi) : foreach ($multi as $element) :
283 $copyOver = NULL;
284
285 if ('image'==$tag and 'rss'==$ns) :
286 $this->inImage = true;
287 $childPath = array();
288 $co = NULL;
289 elseif ('textinput'==strtolower($tag) and 'rss'==$ns) :
290 $this->inTextInput = true;
291 $childPath = array();
292 $co = NULL;
293 else :
294 // Determine tag name; check #; increment #
295 $childTag = strtolower($tag);
296 if ('link'==$tag and 'atom'==$ns) :
297 $rel = $this->get_attrib(
298 /*ns=*/ array('', 'http://www.w3.org/2005/Atom'),
299 /*attr=*/ 'rel',
300 $element
301 );
302 if ($rel != 'alternate') :
303 $childTag .= '_'.$rel;
304 endif;
305 $copyOver = $this->get_attrib(
306 /*ns=*/ array('', 'http://www.w3.org/2005/Atom'),
307 /*attr=*/ 'href',
308 $element
309 );
310 elseif ('content'==$tag and 'atom'==$ns) :
311 $childTag = 'atom_'.$tag;
312 endif;
313
314 $childTag = $this->increment_element($ret, $childTag, $ns, $path);
315 $childPath = $path; $childPath[] = strtolower($childTag);
316
317 if (!is_null($copyOver)) :
318 $co = array();
319 $co[implode('_', $childPath)] = $copyOver;
320 else :
321 $co = NULL;
322 endif;
323 endif;
324
325 $arr = $this->{$method}($element, $childPath);
326 if ($co) :
327 $arr = $co + $arr; // Left-hand overwrites right-hand
328 endif;
329
330 if ($this->inImage) :
331 $this->image = $arr + $this->image;
332
333 // Close tag
334 if ('image'==$tag and 'rss'==$ns) : $this->inImage = false; endif;
335 elseif ($this->inTextInput) :
336 $this->textinput = $arr + $this->textinput;
337
338 // Close tag
339 if ('textinput'==$tag and 'rss'==$ns) : $this->inTextInput = false; endif;
340 elseif ($this->is_namespaced($ns)) :
341 if (!isset($ret[$ns])) : $ret[$ns] = array(); endif;
342 $ret[$ns] = $arr + $ret[$ns];
343 else :
344 $ret = $arr + $ret;
345 endif;
346 endforeach; endforeach;
347
348 endforeach; endif;
349 return $ret;
350 } /* MagpieFromSimplePie::handleChildren() */
351
352 /**
353 * MagpieFromSimplePie::get_attrib
354 *
355 * @param array $namespaces
356 * @param string $attr
357 * @param array $element
358 * @param mixed $default
359 */
360 function get_attrib ($namespaces, $attr, $element, $default = NULL) {
361 $ret = $default;
362 if (isset($element['attribs'])) :
363 foreach ($namespaces as $ns) :
364 if (isset($element['attribs'][$ns])
365 and isset($element['attribs'][$ns][$attr])) :
366 $ret = $element['attribs'][$ns][$attr];
367 break;
368 endif;
369 endforeach;
370 endif;
371 return $ret;
372 } /* MagpieFromSimplePie::get_attrib */
373
374 /**
375 * MagpieFromSimplePie::normalize
376 *
377 * @uses MagpieFromSimplePie::is_atom
378 * @uses MagpieFromSimplePie::is_rss
379 * @uses MagpieFromSimplePie::normalize_element
380 * @uses MagpieFromSimplePie::normalize_author_inheritance
381 * @uses MagpieFromSimplePie::normalize_atom_person
382 * @uses MagpieFromSimplePie::normalize_enclosure
383 * @uses MagpieFromSimplePie::normalize_category
384 * @uses MagpieFromSimplePie::normalize_dc_subject
385 * @uses FeedTime
386 * @uses FeedTime::timestamp
387 */
388 function normalize () {
389 if (!is_null($this->channel)) :
390 // Normalize channel data
391 if ( $this->is_atom() ) :
392 // Atom 1.0 elements <=> Atom 0.3 elements (Thanks, o brilliant wordsmiths of the Atom 1.0 standard!)
393 if ($this->feed_version() < 1.0) :
394 $this->normalize_element($this->channel, 'tagline', $this->channel, 'subtitle');
395 $this->normalize_element($this->channel, 'copyright', $this->channel, 'rights');
396 $this->normalize_element($this->channel, 'modified', $this->channel, 'updated');
397 else :
398 $this->normalize_element($this->channel, 'subtitle', $this->channel, 'tagline');
399 $this->normalize_element($this->channel, 'rights', $this->channel, 'copyright');
400 $this->normalize_element($this->channel, 'updated', $this->channel, 'modified');
401 endif;
402 $this->normalize_element($this->channel, 'author', $this->channel['dc'], 'creator', 'normalize_atom_person');
403 $this->normalize_element($this->channel, 'contributor', $this->channel['dc'], 'contributor', 'normalize_atom_person');
404
405 // Atom elements to RSS elements
406 $this->normalize_element($this->channel, 'subtitle', $this->channel, 'description');
407
408 if ( isset($this->channel['logo']) ) :
409 $this->normalize_element($this->channel, 'logo', $this->image, 'url');
410 $this->normalize_element($this->channel, 'link', $this->image, 'link');
411 $this->normalize_element($this->channel, 'title', $this->image, 'title');
412 endif;
413
414 elseif ( $this->is_rss() ) :
415 // Normalize image element from where stupid MagpieRSS puts it
416 //$this->normalize_element($this->channel, 'image_title', $this->image, 'title');
417 //$this->normalize_element($this->channel, 'image_link', $this->image, 'link');
418 //$this->normalize_element($this->channel, 'image_url', $this->image, 'url');
419
420 // ... and, gag, textInput
421 //$this->normalize_element($this->channel, 'textinput_title', $this->textinput, 'title');
422 //$this->normalize_element($this->channel, 'textinput_link', $this->textinput, 'link');
423 //$this->normalize_element($this->channel, 'textinput_name', $this->textinput, 'name');
424 //$this->normalize_element($this->channel, 'textinput_description', $this->textinput, 'description');
425
426 // RSS elements to Atom elements
427 $this->normalize_element($this->channel, 'description', $this->channel, 'tagline'); // Atom 0.3
428 $this->normalize_element($this->channel, 'description', $this->channel, 'subtitle'); // Atom 1.0 (yay wordsmithing!)
429 $this->normalize_element($this->image, 'url', $this->channel, 'logo');
430 endif;
431 endif;
432
433 if (!is_null($this->items)) :
434 // Now loop through and normalize item data
435 for ( $i = 0; $i < count($this->items); $i++) :
436 $item = $this->items[$i];
437
438 // if atom populate rss fields and normalize 0.3 and 1.0 feeds
439 if ( $this->is_atom() ) :
440 // Atom 1.0 elements <=> Atom 0.3 elements
441 if ($this->feed_version() < 1.0) :
442 $this->normalize_element($item, 'modified', $item, 'updated');
443 $this->normalize_element($item, 'issued', $item, 'published');
444 else :
445 $this->normalize_element($item, 'updated', $item, 'modified');
446 $this->normalize_element($item, 'published', $item, 'issued');
447 endif;
448
449 $this->normalize_author_inheritance($item, $this->originals[$i]);
450
451 // Atom elements to RSS elements
452 $this->normalize_element($item, 'author', $item['dc'], 'creator', 'normalize_atom_person');
453 $this->normalize_element($item, 'contributor', $item['dc'], 'contributor', 'normalize_atom_person');
454 $this->normalize_element($item, 'summary', $item, 'description');
455 $this->normalize_element($item, 'atom_content', $item['content'], 'encoded');
456 $this->normalize_element($item, 'link_enclosure', $item, 'enclosure', 'normalize_enclosure');
457
458 // Categories
459 if ( isset($item['category#']) ) : // Atom 1.0 categories to dc:subject and RSS 2.0 categories
460 $this->normalize_element($item, 'category', $item['dc'], 'subject', 'normalize_category');
461 elseif ( isset($item['dc']['subject#']) ) : // dc:subject to Atom 1.0 and RSS 2.0 categories
462 $this->normalize_element($item['dc'], 'subject', $item, 'category', 'normalize_dc_subject');
463 endif;
464
465 // Normalized item timestamp
466 $item_date = (isset($item['published']) ) ? $item['published'] : $item['updated'];
467 elseif ( $this->is_rss() ) :
468 // RSS elements to Atom elements
469 $this->normalize_element($item, 'description', $item, 'summary');
470 $this->normalize_element($item, 'enclosure', $item, 'link_enclosure', 'normalize_enclosure');
471
472 // Categories
473 if ( isset($item['category#']) ) : // RSS 2.0 categories to dc:subject and Atom 1.0 categories
474 $this->normalize_element($item, 'category', $item['dc'], 'subject', 'normalize_category');
475 elseif ( isset($item['dc']['subject#']) ) : // dc:subject to Atom 1.0 and RSS 2.0 categories
476 $this->normalize_element($item['dc'], 'subject', $item, 'category', 'normalize_dc_subject');
477 endif;
478
479 // Normalized item timestamp
480 if (isset($item['pubdate'])) :
481 $item_date = $item['pubdate'];
482 elseif (isset($item['dc']['date'])) :
483 $item_date = $item['dc']['date'];
484 else :
485 $item_date = null;
486 endif;
487 endif;
488
489 if ( $item_date ) :
490 $date_timestamp = new FeedTime($item_date);
491
492 if (!$date_timestamp->failed()) :
493 $item['date_timestamp'] = $date_timestamp->timestamp();
494 endif;
495 endif;
496
497 $this->items[$i] = $item;
498 endfor;
499 endif;
500 } /* MagpieFromSimplePie::normalize() */
501
502 /**
503 * MagpieFromSimplePie::normalize_author_inheritance
504 *
505 * @param SimplePie_Item $original
506 *
507 * @uses SimplePie_Item::get_authors
508 * @uses SimplePie_Author::get_name
509 * @uses SimplePie_Author::get_link
510 * @uses SimplePie_Author::get_email
511 * @uses MagpieFromSimplePie::increment_element
512 */
513 function normalize_author_inheritance (&$item, $original) {
514 // "If an atom:entry element does not contain
515 // atom:author elements, then the atom:author elements
516 // of the contained atom:source element are considered
517 // to apply. In an Atom Feed Document, the atom:author
518 // elements of the containing atom:feed element are
519 // considered to apply to the entry if there are no
520 // atom:author elements in the locations described
521 // above." <http://atompub.org/2005/08/17/draft-ietf-atompub-format-11.html#rfc.section.4.2.1>
522 if (!isset($item["author#"])) :
523 $authors = $original->get_authors();
524 foreach ($authors as $author) :
525 $tag = $this->increment_element($item, 'author', 'atom', array());
526 $item[$tag] = $item["{$tag}_name"] = $author->get_name();
527 if ($author->get_link()) : $item["{$tag}_uri"] = $item["{$tag}_url"] = $author->get_link(); endif;
528 if ($author->get_email()) : $item["{$tag}_email"] = $author->get_email(); endif;
529 endforeach;
530 endif;
531 } /* MagpieFromSimplePie::normalize_author_inheritance() */
532
533 /**
534 * MagpieFromSimplePie::normalize_element
535 * Simplify the logic for normalize(). Makes sure that count of elements
536 * and each of multiple elements is normalized properly. If you need to
537 * mess with things like attributes or change formats or the like, pass
538 * it a callback to handle each element.
539 *
540 * @param array &$source
541 * @param string $from
542 * @param array &$dest
543 * @param string $to
544 * @param mixed $via
545 */
546 function normalize_element (&$source, $from, &$dest, $to, $via = NULL) {
547 if (isset($source[$from]) or isset($source["{$from}#"])) :
548 if (isset($source["{$from}#"])) :
549 $n = $source["{$from}#"];
550 $dest["{$to}#"] = $source["{$from}#"];
551 else :
552 $n = 1;
553 endif;
554
555 for ($i = 1; $i <= $n; $i++) :
556 if (isset($via) and is_callable(array($this, $via))) : // custom callback for ninja attacks
557 $this->{$via}($source, $from, $dest, $to, $i);
558 else : // just make it the same
559 $from_id = $this->element_id($from, $i);
560 $to_id = $this->element_id($to, $i);
561
562 if (isset($source[$from_id])) : // Avoid PHP notice nastygrams
563 $dest[$to_id] = $source[$from_id];
564 endif;
565 endif;
566 endfor;
567 endif;
568 } /* MagpieFromSimplePie::normalize_element */
569
570 /**
571 * MagpieFromSimplePie::normalize_enclosure
572 *
573 * @param array &$source
574 * @param string $from
575 * @param array &$dest
576 * @param string $to
577 * @param int $i
578 *
579 * @uses MagpieFromSimplePie::element_id
580 */
581 function normalize_enclosure (&$source, $from, &$dest, $to, $i) {
582 $id_from = $this->element_id($from, $i);
583 $id_to = $this->element_id($to, $i);
584 if (isset($source["{$id_from}@"])) :
585 foreach (explode(',', $source["{$id_from}@"]) as $attr) :
586 if ($from=='link_enclosure' and $attr=='href') : // from Atom
587 $dest["{$id_to}@url"] = $source["{$id_from}@{$attr}"];
588 $dest["{$id_to}"] = $source["{$id_from}@{$attr}"];
589 elseif ($from=='enclosure' and $attr=='url') : // from RSS
590 $dest["{$id_to}@href"] = $source["{$id_from}@{$attr}"];
591 $dest["{$id_to}"] = $source["{$id_from}@{$attr}"];
592 else :
593 $dest["{$id_to}@{$attr}"] = $source["{$id_from}@{$attr}"];
594 endif;
595 endforeach;
596 endif;
597 } /* MagpieFromSimplePie::normalize_enclosure */
598
599 /**
600 * MagpieFromSimplePie::normalize_atom_person
601 *
602 * @param array &$source
603 * @param string $person
604 * @param array &$dest
605 * @param string $to
606 * @param int $i
607 *
608 *
609 * @uses MagpieFromSimplePie::element_id
610 */
611 function normalize_atom_person (&$source, $person, &$dest, $to, $i) {
612 $id = $this->element_id($person, $i);
613 $id_to = $this->element_id($to, $i);
614
615 // Atom 0.3 <=> Atom 1.0
616 if ($this->feed_version() >= 1.0) :
617 $used = 'uri'; $norm = 'url';
618 else :
619 $used = 'url'; $norm = 'uri';
620 endif;
621
622 if (isset($source["{$id}_{$used}"])) :
623 $dest["{$id_to}_{$norm}"] = $source["{$id}_{$used}"];
624 endif;
625
626 // Atom to RSS 2.0 and Dublin Core
627 // RSS 2.0 person strings should be valid e-mail addresses if possible.
628 if (isset($source["{$id}_email"])) :
629 $rss_author = $source["{$id}_email"];
630 endif;
631 if (isset($source["{$id}_name"])) :
632 $rss_author = $source["{$id}_name"]
633 . (isset($rss_author) ? " <$rss_author>" : '');
634 endif;
635 if (isset($rss_author)) :
636 $source[$id] = $rss_author; // goes to top-level author or contributor
637 $dest[$id_to] = $rss_author; // goes to dc:creator or dc:contributor
638 endif;
639 } /* MagpieFromSimplePie::normalize_atom_person */
640
641 /**
642 * MagpieFromSimplePie::normalize_category: Normalize Atom 1.0 and
643 * RSS 2.0 categories to Dublin Core...
644 *
645 * @param array &$source
646 * @param string $from
647 * @param array &$dest
648 * @param string $to
649 * @param int $i
650 *
651 * @uses MagpieFromSimplePie::element_id
652 * @uses MagpieFromSimplePie::is_rss
653 */
654 function normalize_category (&$source, $from, &$dest, $to, $i) {
655 $cat_id = $this->element_id($from, $i);
656 $dc_id = $this->element_id($to, $i);
657
658 // first normalize category elements: Atom 1.0 <=> RSS 2.0
659 if ( isset($source["{$cat_id}@term"]) ) : // category identifier
660 $source[$cat_id] = $source["{$cat_id}@term"];
661 elseif ( $this->is_rss() ) :
662 $source["{$cat_id}@term"] = $source[$cat_id];
663 endif;
664
665 if ( isset($source["{$cat_id}@scheme"]) ) : // URI to taxonomy
666 $source["{$cat_id}@domain"] = $source["{$cat_id}@scheme"];
667 elseif ( isset($source["{$cat_id}@domain"]) ) :
668 $source["{$cat_id}@scheme"] = $source["{$cat_id}@domain"];
669 endif;
670
671 // Now put the identifier into dc:subject
672 $dest[$dc_id] = $source[$cat_id];
673 } /* MagpieFromSimplePie::normalize_category */
674
675 /**
676 * MagpieFromSimplePie::normalize_dc_subject: Normalize Dublin Core
677 * "subject" elements to Atom 1.0 and RSS 2.0 categories.
678 *
679 * @param array &$source
680 * @param string $from
681 * @param array &$dest
682 * @param string $to
683 * @param int $i
684 *
685 * @uses MagpieFromSimplePie::element_id
686 */
687 function normalize_dc_subject (&$source, $from, &$dest, $to, $i) {
688 $dc_id = $this->element_id($from, $i);
689 $cat_id = $this->element_id($to, $i);
690
691 $dest[$cat_id] = $source[$dc_id]; // RSS 2.0
692 $dest["{$cat_id}@term"] = $source[$dc_id]; // Atom 1.0
693 }
694
695 /**
696 * MagpieFromSimplePie::element_id
697 * Magic ID function for multiple elemenets.
698 * Can be called as static MagpieRSS::element_id()
699 *
700 * @param string $el
701 * @param int $counter
702 * @return string
703 */
704 function element_id ($el, $counter) {
705 return $el . (($counter > 1) ? '#'.$counter : '');
706 } /* MagpieFromSimplePie::element_id */
707
708 /**
709 * MagpieFromSimplePie::increment_element
710 *
711 * @param array &$data
712 * @param string $childTag
713 * @param string $ns
714 * @param array $path
715 */
716 function increment_element (&$data, $childTag, $ns, $path) {
717 $counterIndex = strtolower(implode('_', array_merge($path, array($childTag.'#'))));
718 if ($this->is_namespaced($ns)) :
719 if (!isset($data[$ns])) : $data[$ns] = array(); endif;
720 if (!isset($data[$ns][$counterIndex])) : $data[$ns][$counterIndex] = 0; endif;
721 $data[$ns][$counterIndex] += 1;
722 $N = $data[$ns][$counterIndex];
723 else :
724 if (!isset($data[$counterIndex])) : $data[$counterIndex] = 0; endif;
725 $data[$counterIndex] += 1;
726 $N = $data[$counterIndex];
727 endif;
728
729 if ($N > 1) :
730 $childTag .= '#'.$N;
731 endif;
732 return $childTag;
733 } /* MagpieFromSimplePie::increment_element */
734
735 /**
736 * MagpieFromSimplePie::is_namespaced
737 *
738 * @param string $ns
739 * @return bool
740 *
741 * @uses MagpieFromSimplePie::is_atom
742 * @uses MagpieFromSimplePie::is_rdf
743 */
744 function is_namespaced ($ns, $attribute = false) {
745 // Atom vs. RSS
746 if ($this->is_atom()) : $root = array('', 'atom');
747 else : $root = array('', 'rss');
748 endif;
749
750 // RDF formats; namespaced in attribs but not in elements
751 if (!$attribute and $this->is_rdf()) :
752 $root[] = 'rdf';
753 endif;
754
755 return !in_array(strtolower($ns), $root);
756 } /* MagpieFromSimplePie::is_namespaced */
757
758 /**
759 * MagpieFromSimplePie::is_atom
760 *
761 * @return bool
762 */
763 function is_atom () {
764 return $this->pie->get_type() & SIMPLEPIE_TYPE_ATOM_ALL;
765 } /* MagpieFromSimplePie::increment_element */
766
767 /**
768 * MagpieFromSimplePie::is_rss
769 *
770 * @return bool
771 */
772 function is_rss () {
773 return $this->pie->get_type() & SIMPLEPIE_TYPE_RSS_ALL;
774 } /* MagpieFromSimplePie::is_rss */
775
776 /**
777 * MagpieFromSimplePie::is_rdf
778 *
779 * @return bool
780 */
781 function is_rdf () {
782 return $this->pie->get_type() & SIMPLEPIE_TYPE_RSS_RDF;
783 } /* MagpieFromSimplePie::is_rdf */
784
785 /**
786 * MagpieFromSimplePie::feed_version
787 *
788 * @return float
789 */
790 function feed_version () {
791 $map = array (
792 SIMPLEPIE_TYPE_ATOM_10 => 1.0,
793 SIMPLEPIE_TYPE_ATOM_03 => 0.3,
794 SIMPLEPIE_TYPE_RSS_090 => 0.90,
795 SIMPLEPIE_TYPE_RSS_091 => 0.91,
796 SIMPLEPIE_TYPE_RSS_092 => 0.92,
797 SIMPLEPIE_TYPE_RSS_093 => 0.93,
798 SIMPLEPIE_TYPE_RSS_094 => 0.94,
799 SIMPLEPIE_TYPE_RSS_10 => 1.0,
800 SIMPLEPIE_TYPE_RSS_20 => 2.0,
801 );
802
803 $ret = NULL; $type = $this->pie->get_type();
804 foreach ($map as $flag => $version) :
805 if ($type & $flag) :
806 $ret = $version;
807 break;
808 endif;
809 endforeach;
810 return $ret;
811 } /* MagpieFromSimplePie::feed_version */
812
813 } /* class MagpieFromSimplePie */
814
815