PluginProbe
FeedWordPress / 2024.0428
FeedWordPress v2024.0428
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 2024.0428, at magpiefromsimplepie.class.php

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