PluginProbe
FeedWordPress / 2022.0208
FeedWordPress v2022.0208
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 2022.0208, at magpiefromsimplepie.class.php

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