PluginProbe
FeedWordPress / 2013.0504
FeedWordPress v2013.0504
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 2013.0504, at magpiefromsimplepie.class.php

822 lines 26.7 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
159 return apply_filters('feedwordpress_magpiefromsimplepie_processfeeddata', $ret, $data, $this);
160 } /* MagpieFromSimplePie::processFeedData() */
161
162 /**
163 * MagpieFromSimplePie::processChannelData
164 *
165 * @param array $data
166 * @param array $path
167 * @return array
168 *
169 * @uses MagpieFromSimplePie::handleAttributes
170 * @uses MagpieFromSimplePie::handleChildren
171 */
172 function processChannelData ($data, $path = array()) {
173 $ret = array();
174 $tagPath = strtolower(implode('_', $path));
175
176 // Only process at the right level
177 if (strlen($tagPath) > 0
178 and isset($data['data'])
179 and strlen($data['data']) > 0) :
180 $ret[$tagPath] = $data['data'];
181 endif;
182
183 $ret = $this->handleAttributes($data, $path)
184 + $this->handleChildren($data, $path, 'processChannelData')
185 + $ret;
186
187 return apply_filters('feedwordpress_magpiefromsimplepie_processchanneldata', $ret, $data, $path, $this);
188 } /* MagpieFromSimplePie::processChannelData() */
189
190 /**
191 * MagpieFromSimplePie::processItemData
192 *
193 * @param array $data
194 * @param array $path
195 * @return array
196 *
197 * @uses MagpieFromSimplePie::handleAttributes
198 * @uses MagpieFromSimplePie::handleChildren
199 */
200 function processItemData ($data, $path = array()) {
201 $ret = array();
202 $tagPath = strtolower(implode('_', $path));
203
204 if (strlen($tagPath) > 0 and isset($data['data']) and strlen($data['data']) > 0) :
205 $ret[$tagPath] = $data['data'];
206 endif;
207
208 // Set up xml:base to be recorded in array
209 if (isset($data['xml_base_explicit']) and $data['xml_base_explicit']) :
210 $data['attribs']['']['xml:base'] = $data['xml_base'];
211 endif;
212
213 $ret = $this->handleAttributes($data, $path)
214 + $this->handleChildren($data, $path, 'processItemData')
215 + $ret;
216
217 return apply_filters('feedwordpress_magpiefromsimplepie_processitemdata', $ret, $data, $path, $this);
218 } /* MagpieFromSimplePie::processItemData() */
219
220 /**
221 * MagpieFromSimplePie::handleAttributes
222 *
223 * @param array $data
224 * @param array $path
225 * @return array
226 */
227 function handleAttributes ($data, $path) {
228 $tagPath = strtolower(implode('_', $path));
229 $ret = array();
230 if (isset($data['attribs'])) : foreach ($data['attribs'] as $ns => $pairs) :
231 if (isset($this->_XMLNS_FAMILIAR[$ns])) :
232 $ns = $this->_XMLNS_FAMILIAR[$ns];
233 endif;
234
235 foreach ($pairs as $attr => $value) :
236 $attr = strtolower($attr);
237 if ($ns=='rdf' and $attr=='about') :
238 $ret['about'] = $value;
239 elseif (strlen($tagPath) > 0) :
240 if (strlen($ns) > 0 and $this->is_namespaced($ns, /*attrib=*/ true)) :
241 $attr = $ns.':'.$attr;
242 endif;
243
244 $ret[$tagPath.'@'.$attr] = $value;
245 if (isset($ret[$tagPath.'@']) and strlen($ret[$tagPath.'@'])>0) :
246 $ret[$tagPath.'@'] .= ',';
247 else :
248 $ret[$tagPath.'@'] = '';
249 endif;
250 $ret[$tagPath.'@'] .= $attr;
251 endif;
252 endforeach;
253 endforeach; endif;
254
255 return apply_filters('feedwordpress_magpiefromsimplepie_handleattributes', $ret, $data, $path, $this);
256 } /* MagpieFromSimplePie::handleAttributes() */
257
258 var $inImage = false;
259 var $inTextInput = false;
260
261 /**
262 * MagpieFromSimplePie::handleChildren
263 *
264 * @param array $data
265 * @param array $path
266 * @return array
267 *
268 * @uses MagpieFromSimplePie::get_attrib
269 * @uses MagpieFromSimplePie::is_atom
270 * @uses MagpieFromSimplePie::increment_element
271 * @uses MagpieFromSimplePie::processItemData
272 */
273 function handleChildren ($data, $path = array(), $method = 'processItemData') {
274 $tagPath = strtolower(implode('_', $path));
275 $ret = array();
276 if (isset($data['child'])) : foreach ($data['child'] as $ns => $elements) :
277 if (isset($this->_XMLNS_FAMILIAR[$ns])) :
278 $ns = $this->_XMLNS_FAMILIAR[$ns];
279 endif;
280 if (''==$ns) :
281 $ns = ($this->is_atom() ? 'atom' : 'rss');
282 endif;
283
284 foreach ($elements as $tag => $multi) : foreach ($multi as $element) :
285 $copyOver = NULL;
286
287 if ('image'==$tag and 'rss'==$ns) :
288 $this->inImage = true;
289 $childPath = array();
290 $co = NULL;
291 elseif ('textinput'==strtolower($tag) and 'rss'==$ns) :
292 $this->inTextInput = true;
293 $childPath = array();
294 $co = NULL;
295 else :
296 // Determine tag name; check #; increment #
297 $childTag = strtolower($tag);
298 if ('link'==$tag and 'atom'==$ns) :
299 $rel = $this->get_attrib(
300 /*ns=*/ array('', 'http://www.w3.org/2005/Atom'),
301 /*attr=*/ 'rel',
302 $element
303 );
304 if ($rel != 'alternate') :
305 $childTag .= '_'.$rel;
306 endif;
307 $copyOver = $this->get_attrib(
308 /*ns=*/ array('', 'http://www.w3.org/2005/Atom'),
309 /*attr=*/ 'href',
310 $element
311 );
312 elseif ('content'==$tag and 'atom'==$ns) :
313 $childTag = 'atom_'.$tag;
314 endif;
315
316 $childTag = $this->increment_element($ret, $childTag, $ns, $path);
317 $childPath = $path; $childPath[] = strtolower($childTag);
318
319 if (!is_null($copyOver)) :
320 $co = array();
321 $co[implode('_', $childPath)] = $copyOver;
322 else :
323 $co = NULL;
324 endif;
325 endif;
326
327 $arr = $this->{$method}($element, $childPath);
328 if ($co) :
329 $arr = $co + $arr; // Left-hand overwrites right-hand
330 endif;
331
332 if ($this->inImage) :
333 $this->image = $arr + $this->image;
334
335 // Close tag
336 if ('image'==$tag and 'rss'==$ns) : $this->inImage = false; endif;
337 elseif ($this->inTextInput) :
338 $this->textinput = $arr + $this->textinput;
339
340 // Close tag
341 if ('textinput'==$tag and 'rss'==$ns) : $this->inTextInput = false; endif;
342 elseif ($this->is_namespaced($ns)) :
343 if (!isset($ret[$ns])) : $ret[$ns] = array(); endif;
344 $ret[$ns] = $arr + $ret[$ns];
345 else :
346 $ret = $arr + $ret;
347 endif;
348 endforeach; endforeach;
349
350 endforeach; endif;
351
352 return apply_filters('feedwordpress_magpiefromsimplepie_handlechildren', $ret, $data, $path, $method, $this);
353 } /* MagpieFromSimplePie::handleChildren() */
354
355 /**
356 * MagpieFromSimplePie::get_attrib
357 *
358 * @param array $namespaces
359 * @param string $attr
360 * @param array $element
361 * @param mixed $default
362 */
363 function get_attrib ($namespaces, $attr, $element, $default = NULL) {
364 $ret = $default;
365 if (isset($element['attribs'])) :
366 foreach ($namespaces as $ns) :
367 if (isset($element['attribs'][$ns])
368 and isset($element['attribs'][$ns][$attr])) :
369 $ret = $element['attribs'][$ns][$attr];
370 break;
371 endif;
372 endforeach;
373 endif;
374 return $ret;
375 } /* MagpieFromSimplePie::get_attrib */
376
377 /**
378 * MagpieFromSimplePie::normalize
379 *
380 * @uses MagpieFromSimplePie::is_atom
381 * @uses MagpieFromSimplePie::is_rss
382 * @uses MagpieFromSimplePie::normalize_element
383 * @uses MagpieFromSimplePie::normalize_author_inheritance
384 * @uses MagpieFromSimplePie::normalize_atom_person
385 * @uses MagpieFromSimplePie::normalize_enclosure
386 * @uses MagpieFromSimplePie::normalize_category
387 * @uses MagpieFromSimplePie::normalize_dc_subject
388 * @uses FeedTime
389 * @uses FeedTime::timestamp
390 */
391 function normalize () {
392 do_action('feedwordpress_magpiefromsimplepie_normalize_pre', $this);
393
394 if (!is_null($this->channel)) :
395 // Normalize channel data
396 if ( $this->is_atom() ) :
397 // Atom 1.0 elements <=> Atom 0.3 elements (Thanks, o brilliant wordsmiths of the Atom 1.0 standard!)
398 if ($this->feed_version() < 1.0) :
399 $this->normalize_element($this->channel, 'tagline', $this->channel, 'subtitle');
400 $this->normalize_element($this->channel, 'copyright', $this->channel, 'rights');
401 $this->normalize_element($this->channel, 'modified', $this->channel, 'updated');
402 else :
403 $this->normalize_element($this->channel, 'subtitle', $this->channel, 'tagline');
404 $this->normalize_element($this->channel, 'rights', $this->channel, 'copyright');
405 $this->normalize_element($this->channel, 'updated', $this->channel, 'modified');
406 endif;
407 $this->normalize_element($this->channel, 'author', $this->channel['dc'], 'creator', 'normalize_atom_person');
408 $this->normalize_element($this->channel, 'contributor', $this->channel['dc'], 'contributor', 'normalize_atom_person');
409
410 // Atom elements to RSS elements
411 $this->normalize_element($this->channel, 'subtitle', $this->channel, 'description');
412
413 if ( isset($this->channel['logo']) ) :
414 $this->normalize_element($this->channel, 'logo', $this->image, 'url');
415 $this->normalize_element($this->channel, 'link', $this->image, 'link');
416 $this->normalize_element($this->channel, 'title', $this->image, 'title');
417 endif;
418
419 elseif ( $this->is_rss() ) :
420 // Normalize image element from where stupid MagpieRSS puts it
421 //$this->normalize_element($this->channel, 'image_title', $this->image, 'title');
422 //$this->normalize_element($this->channel, 'image_link', $this->image, 'link');
423 //$this->normalize_element($this->channel, 'image_url', $this->image, 'url');
424
425 // ... and, gag, textInput
426 //$this->normalize_element($this->channel, 'textinput_title', $this->textinput, 'title');
427 //$this->normalize_element($this->channel, 'textinput_link', $this->textinput, 'link');
428 //$this->normalize_element($this->channel, 'textinput_name', $this->textinput, 'name');
429 //$this->normalize_element($this->channel, 'textinput_description', $this->textinput, 'description');
430
431 // RSS elements to Atom elements
432 $this->normalize_element($this->channel, 'description', $this->channel, 'tagline'); // Atom 0.3
433 $this->normalize_element($this->channel, 'description', $this->channel, 'subtitle'); // Atom 1.0 (yay wordsmithing!)
434 $this->normalize_element($this->image, 'url', $this->channel, 'logo');
435 endif;
436 endif;
437
438 if (!is_null($this->items)) :
439 // Now loop through and normalize item data
440 for ( $i = 0; $i < count($this->items); $i++) :
441 $item = $this->items[$i];
442
443 // if atom populate rss fields and normalize 0.3 and 1.0 feeds
444 if ( $this->is_atom() ) :
445 // Atom 1.0 elements <=> Atom 0.3 elements
446 if ($this->feed_version() < 1.0) :
447 $this->normalize_element($item, 'modified', $item, 'updated');
448 $this->normalize_element($item, 'issued', $item, 'published');
449 else :
450 $this->normalize_element($item, 'updated', $item, 'modified');
451 $this->normalize_element($item, 'published', $item, 'issued');
452 endif;
453
454 $this->normalize_author_inheritance($item, $this->originals[$i]);
455
456 // Atom elements to RSS elements
457 $this->normalize_element($item, 'author', $item['dc'], 'creator', 'normalize_atom_person');
458 $this->normalize_element($item, 'contributor', $item['dc'], 'contributor', 'normalize_atom_person');
459 $this->normalize_element($item, 'summary', $item, 'description');
460 $this->normalize_element($item, 'atom_content', $item['content'], 'encoded');
461 $this->normalize_element($item, 'link_enclosure', $item, 'enclosure', 'normalize_enclosure');
462
463 // Categories
464 if ( isset($item['category#']) ) : // Atom 1.0 categories to dc:subject and RSS 2.0 categories
465 $this->normalize_element($item, 'category', $item['dc'], 'subject', 'normalize_category');
466 elseif ( isset($item['dc']['subject#']) ) : // dc:subject to Atom 1.0 and RSS 2.0 categories
467 $this->normalize_element($item['dc'], 'subject', $item, 'category', 'normalize_dc_subject');
468 endif;
469
470 // Normalized item timestamp
471 $item_date = (isset($item['published']) ) ? $item['published'] : $item['updated'];
472 elseif ( $this->is_rss() ) :
473 // RSS elements to Atom elements
474 $this->normalize_element($item, 'description', $item, 'summary');
475 $this->normalize_element($item, 'enclosure', $item, 'link_enclosure', 'normalize_enclosure');
476
477 // Categories
478 if ( isset($item['category#']) ) : // RSS 2.0 categories to dc:subject and Atom 1.0 categories
479 $this->normalize_element($item, 'category', $item['dc'], 'subject', 'normalize_category');
480 elseif ( isset($item['dc']['subject#']) ) : // dc:subject to Atom 1.0 and RSS 2.0 categories
481 $this->normalize_element($item['dc'], 'subject', $item, 'category', 'normalize_dc_subject');
482 endif;
483
484 // Normalized item timestamp
485 if (isset($item['pubdate'])) :
486 $item_date = $item['pubdate'];
487 elseif (isset($item['dc']['date'])) :
488 $item_date = $item['dc']['date'];
489 else :
490 $item_date = null;
491 endif;
492 endif;
493
494 if ( $item_date ) :
495 $date_timestamp = new FeedTime($item_date);
496
497 if (!$date_timestamp->failed()) :
498 $item['date_timestamp'] = $date_timestamp->timestamp();
499 endif;
500 endif;
501
502 $this->items[$i] = $item;
503 endfor;
504 endif;
505
506 do_action('feedwordpress_magpiefromsimplepie_normalize_post', $this);
507 } /* MagpieFromSimplePie::normalize() */
508
509 /**
510 * MagpieFromSimplePie::normalize_author_inheritance
511 *
512 * @param SimplePie_Item $original
513 *
514 * @uses SimplePie_Item::get_authors
515 * @uses SimplePie_Author::get_name
516 * @uses SimplePie_Author::get_link
517 * @uses SimplePie_Author::get_email
518 * @uses MagpieFromSimplePie::increment_element
519 */
520 function normalize_author_inheritance (&$item, $original) {
521 // "If an atom:entry element does not contain
522 // atom:author elements, then the atom:author elements
523 // of the contained atom:source element are considered
524 // to apply. In an Atom Feed Document, the atom:author
525 // elements of the containing atom:feed element are
526 // considered to apply to the entry if there are no
527 // atom:author elements in the locations described
528 // above." <http://atompub.org/2005/08/17/draft-ietf-atompub-format-11.html#rfc.section.4.2.1>
529 if (!isset($item["author#"])) :
530 $authors = $original->get_authors();
531 foreach ($authors as $author) :
532 $tag = $this->increment_element($item, 'author', 'atom', array());
533 $item[$tag] = $item["{$tag}_name"] = $author->get_name();
534 if ($author->get_link()) : $item["{$tag}_uri"] = $item["{$tag}_url"] = $author->get_link(); endif;
535 if ($author->get_email()) : $item["{$tag}_email"] = $author->get_email(); endif;
536 endforeach;
537 endif;
538 } /* MagpieFromSimplePie::normalize_author_inheritance() */
539
540 /**
541 * MagpieFromSimplePie::normalize_element
542 * Simplify the logic for normalize(). Makes sure that count of elements
543 * and each of multiple elements is normalized properly. If you need to
544 * mess with things like attributes or change formats or the like, pass
545 * it a callback to handle each element.
546 *
547 * @param array &$source
548 * @param string $from
549 * @param array &$dest
550 * @param string $to
551 * @param mixed $via
552 */
553 function normalize_element (&$source, $from, &$dest, $to, $via = NULL) {
554 if (isset($source[$from]) or isset($source["{$from}#"])) :
555 if (isset($source["{$from}#"])) :
556 $n = $source["{$from}#"];
557 $dest["{$to}#"] = $source["{$from}#"];
558 else :
559 $n = 1;
560 endif;
561
562 for ($i = 1; $i <= $n; $i++) :
563 if (isset($via) and is_callable(array($this, $via))) : // custom callback for ninja attacks
564 $this->{$via}($source, $from, $dest, $to, $i);
565 else : // just make it the same
566 $from_id = $this->element_id($from, $i);
567 $to_id = $this->element_id($to, $i);
568
569 if (isset($source[$from_id])) : // Avoid PHP notice nastygrams
570 $dest[$to_id] = $source[$from_id];
571 endif;
572 endif;
573 endfor;
574 endif;
575 } /* MagpieFromSimplePie::normalize_element */
576
577 /**
578 * MagpieFromSimplePie::normalize_enclosure
579 *
580 * @param array &$source
581 * @param string $from
582 * @param array &$dest
583 * @param string $to
584 * @param int $i
585 *
586 * @uses MagpieFromSimplePie::element_id
587 */
588 function normalize_enclosure (&$source, $from, &$dest, $to, $i) {
589 $id_from = $this->element_id($from, $i);
590 $id_to = $this->element_id($to, $i);
591 if (isset($source["{$id_from}@"])) :
592 foreach (explode(',', $source["{$id_from}@"]) as $attr) :
593 if ($from=='link_enclosure' and $attr=='href') : // from Atom
594 $dest["{$id_to}@url"] = $source["{$id_from}@{$attr}"];
595 $dest["{$id_to}"] = $source["{$id_from}@{$attr}"];
596 elseif ($from=='enclosure' and $attr=='url') : // from RSS
597 $dest["{$id_to}@href"] = $source["{$id_from}@{$attr}"];
598 $dest["{$id_to}"] = $source["{$id_from}@{$attr}"];
599 else :
600 $dest["{$id_to}@{$attr}"] = $source["{$id_from}@{$attr}"];
601 endif;
602 endforeach;
603 endif;
604 } /* MagpieFromSimplePie::normalize_enclosure */
605
606 /**
607 * MagpieFromSimplePie::normalize_atom_person
608 *
609 * @param array &$source
610 * @param string $person
611 * @param array &$dest
612 * @param string $to
613 * @param int $i
614 *
615 *
616 * @uses MagpieFromSimplePie::element_id
617 */
618 function normalize_atom_person (&$source, $person, &$dest, $to, $i) {
619 $id = $this->element_id($person, $i);
620 $id_to = $this->element_id($to, $i);
621
622 // Atom 0.3 <=> Atom 1.0
623 if ($this->feed_version() >= 1.0) :
624 $used = 'uri'; $norm = 'url';
625 else :
626 $used = 'url'; $norm = 'uri';
627 endif;
628
629 if (isset($source["{$id}_{$used}"])) :
630 $dest["{$id_to}_{$norm}"] = $source["{$id}_{$used}"];
631 endif;
632
633 // Atom to RSS 2.0 and Dublin Core
634 // RSS 2.0 person strings should be valid e-mail addresses if possible.
635 if (isset($source["{$id}_email"])) :
636 $rss_author = $source["{$id}_email"];
637 endif;
638 if (isset($source["{$id}_name"])) :
639 $rss_author = $source["{$id}_name"]
640 . (isset($rss_author) ? " <$rss_author>" : '');
641 endif;
642 if (isset($rss_author)) :
643 $source[$id] = $rss_author; // goes to top-level author or contributor
644 $dest[$id_to] = $rss_author; // goes to dc:creator or dc:contributor
645 endif;
646 } /* MagpieFromSimplePie::normalize_atom_person */
647
648 /**
649 * MagpieFromSimplePie::normalize_category: Normalize Atom 1.0 and
650 * RSS 2.0 categories to Dublin Core...
651 *
652 * @param array &$source
653 * @param string $from
654 * @param array &$dest
655 * @param string $to
656 * @param int $i
657 *
658 * @uses MagpieFromSimplePie::element_id
659 * @uses MagpieFromSimplePie::is_rss
660 */
661 function normalize_category (&$source, $from, &$dest, $to, $i) {
662 $cat_id = $this->element_id($from, $i);
663 $dc_id = $this->element_id($to, $i);
664
665 // first normalize category elements: Atom 1.0 <=> RSS 2.0
666 if ( isset($source["{$cat_id}@term"]) ) : // category identifier
667 $source[$cat_id] = $source["{$cat_id}@term"];
668 elseif ( $this->is_rss() ) :
669 $source["{$cat_id}@term"] = $source[$cat_id];
670 endif;
671
672 if ( isset($source["{$cat_id}@scheme"]) ) : // URI to taxonomy
673 $source["{$cat_id}@domain"] = $source["{$cat_id}@scheme"];
674 elseif ( isset($source["{$cat_id}@domain"]) ) :
675 $source["{$cat_id}@scheme"] = $source["{$cat_id}@domain"];
676 endif;
677
678 // Now put the identifier into dc:subject
679 $dest[$dc_id] = $source[$cat_id];
680 } /* MagpieFromSimplePie::normalize_category */
681
682 /**
683 * MagpieFromSimplePie::normalize_dc_subject: Normalize Dublin Core
684 * "subject" elements to Atom 1.0 and RSS 2.0 categories.
685 *
686 * @param array &$source
687 * @param string $from
688 * @param array &$dest
689 * @param string $to
690 * @param int $i
691 *
692 * @uses MagpieFromSimplePie::element_id
693 */
694 function normalize_dc_subject (&$source, $from, &$dest, $to, $i) {
695 $dc_id = $this->element_id($from, $i);
696 $cat_id = $this->element_id($to, $i);
697
698 $dest[$cat_id] = $source[$dc_id]; // RSS 2.0
699 $dest["{$cat_id}@term"] = $source[$dc_id]; // Atom 1.0
700 }
701
702 /**
703 * MagpieFromSimplePie::element_id
704 * Magic ID function for multiple elemenets.
705 * Can be called as static MagpieRSS::element_id()
706 *
707 * @param string $el
708 * @param int $counter
709 * @return string
710 */
711 function element_id ($el, $counter) {
712 return $el . (($counter > 1) ? '#'.$counter : '');
713 } /* MagpieFromSimplePie::element_id */
714
715 /**
716 * MagpieFromSimplePie::increment_element
717 *
718 * @param array &$data
719 * @param string $childTag
720 * @param string $ns
721 * @param array $path
722 */
723 function increment_element (&$data, $childTag, $ns, $path) {
724 $counterIndex = strtolower(implode('_', array_merge($path, array($childTag.'#'))));
725 if ($this->is_namespaced($ns)) :
726 if (!isset($data[$ns])) : $data[$ns] = array(); endif;
727 if (!isset($data[$ns][$counterIndex])) : $data[$ns][$counterIndex] = 0; endif;
728 $data[$ns][$counterIndex] += 1;
729 $N = $data[$ns][$counterIndex];
730 else :
731 if (!isset($data[$counterIndex])) : $data[$counterIndex] = 0; endif;
732 $data[$counterIndex] += 1;
733 $N = $data[$counterIndex];
734 endif;
735
736 if ($N > 1) :
737 $childTag .= '#'.$N;
738 endif;
739 return $childTag;
740 } /* MagpieFromSimplePie::increment_element */
741
742 /**
743 * MagpieFromSimplePie::is_namespaced
744 *
745 * @param string $ns
746 * @return bool
747 *
748 * @uses MagpieFromSimplePie::is_atom
749 * @uses MagpieFromSimplePie::is_rdf
750 */
751 function is_namespaced ($ns, $attribute = false) {
752 // Atom vs. RSS
753 if ($this->is_atom()) : $root = array('', 'atom');
754 else : $root = array('', 'rss');
755 endif;
756
757 // RDF formats; namespaced in attribs but not in elements
758 if (!$attribute and $this->is_rdf()) :
759 $root[] = 'rdf';
760 endif;
761
762 return !in_array(strtolower($ns), $root);
763 } /* MagpieFromSimplePie::is_namespaced */
764
765 /**
766 * MagpieFromSimplePie::is_atom
767 *
768 * @return bool
769 */
770 function is_atom () {
771 return $this->pie->get_type() & SIMPLEPIE_TYPE_ATOM_ALL;
772 } /* MagpieFromSimplePie::increment_element */
773
774 /**
775 * MagpieFromSimplePie::is_rss
776 *
777 * @return bool
778 */
779 function is_rss () {
780 return $this->pie->get_type() & SIMPLEPIE_TYPE_RSS_ALL;
781 } /* MagpieFromSimplePie::is_rss */
782
783 /**
784 * MagpieFromSimplePie::is_rdf
785 *
786 * @return bool
787 */
788 function is_rdf () {
789 return $this->pie->get_type() & SIMPLEPIE_TYPE_RSS_RDF;
790 } /* MagpieFromSimplePie::is_rdf */
791
792 /**
793 * MagpieFromSimplePie::feed_version
794 *
795 * @return float
796 */
797 function feed_version () {
798 $map = array (
799 SIMPLEPIE_TYPE_ATOM_10 => 1.0,
800 SIMPLEPIE_TYPE_ATOM_03 => 0.3,
801 SIMPLEPIE_TYPE_RSS_090 => 0.90,
802 SIMPLEPIE_TYPE_RSS_091 => 0.91,
803 SIMPLEPIE_TYPE_RSS_092 => 0.92,
804 SIMPLEPIE_TYPE_RSS_093 => 0.93,
805 SIMPLEPIE_TYPE_RSS_094 => 0.94,
806 SIMPLEPIE_TYPE_RSS_10 => 1.0,
807 SIMPLEPIE_TYPE_RSS_20 => 2.0,
808 );
809
810 $ret = NULL; $type = $this->pie->get_type();
811 foreach ($map as $flag => $version) :
812 if ($type & $flag) :
813 $ret = $version;
814 break;
815 endif;
816 endforeach;
817 return $ret;
818 } /* MagpieFromSimplePie::feed_version */
819
820 } /* class MagpieFromSimplePie */
821
822