Index: trunk/extensions/RSS/RELEASE-NOTES |
— | — | @@ -11,8 +11,13 @@ |
12 | 12 | (otherwise using the defaults - PHP will abort the entire program when your |
13 | 13 | memory usage gets too high) |
14 | 14 | * bug 30028 "Error parsing XML for RSS" - improve and harden Extension:RSS when |
15 | | - parsing differently flavoured RSS feeds |
| 15 | + parsing differently flavoured RSS feeds and ATOM feeds |
16 | 16 | |
| 17 | +=== Version 2.00 2012-02-24 === |
| 18 | +* first version which can parse RSS and at least some ATOM feeds |
| 19 | + partial solution of bug 30028 "Error parsing XML for RSS" - improve and harden |
| 20 | + Extension:RSS when parsing differently flavoured RSS feeds and ATOM feeds |
| 21 | + |
17 | 22 | === Version 1.94 2012-02-23 === |
18 | 23 | * changed white list definition and behaviour: |
19 | 24 | |
Index: trunk/extensions/RSS/RSSData.php |
— | — | @@ -15,8 +15,29 @@ |
16 | 16 | return; |
17 | 17 | } |
18 | 18 | $xpath = new DOMXPath( $xml ); |
19 | | - $items = $xpath->query( '/rss/channel/item' ); |
| 19 | + |
| 20 | + // register namespace as below, and apply a regex to the expression |
| 21 | + // http://de3.php.net/manual/en/domxpath.query.php#103461 |
| 22 | + $namespaceURI = $xml->lookupnamespaceURI( NULL ); |
20 | 23 | |
| 24 | + if ( ( null !== $namespaceURI ) ) { |
| 25 | + $defaultNS = "defaultNS"; |
| 26 | + $xpath->registerNamespace( $defaultNS, $namespaceURI ); |
| 27 | + $defaultNS = "defaultNS:"; |
| 28 | + } else { |
| 29 | + $defaultNS = ""; |
| 30 | + } |
| 31 | + |
| 32 | + $q = "/rss/channel/item"; |
| 33 | + $q = preg_replace( '#(::|/\s*|\A)(?![/@].+?|[a-z\-]+::)#', '$1' . $defaultNS . '$2', $q ); |
| 34 | + $items = $xpath->query( $q ); // is it an RSS feed ? |
| 35 | + |
| 36 | + if ( $items->length === 0 ) { |
| 37 | + $q = "/feed/entry"; |
| 38 | + $q = preg_replace( '#(::|/\s*|\A)(?![/@].+?|[a-z\-]+::)#', '$1' . $defaultNS . '$2', $q ); |
| 39 | + $items = $xpath->query( $q ); // is it an ATOM feed ? |
| 40 | + } |
| 41 | + |
21 | 42 | if( $items->length !== 0 ) { |
22 | 43 | foreach ( $items as $item ) { |
23 | 44 | $bit = array(); |
— | — | @@ -37,7 +58,7 @@ |
38 | 59 | $this->items[] = $bit; |
39 | 60 | } |
40 | 61 | } else { |
41 | | - $this->error = 'No RSS items found.'; |
| 62 | + $this->error = 'No RSS//ATOM items found.'; |
42 | 63 | return; |
43 | 64 | } |
44 | 65 | } |
— | — | @@ -52,10 +73,11 @@ |
53 | 74 | * @param $n String: name of the element we have |
54 | 75 | * @return String Name to map it to |
55 | 76 | */ |
56 | | - protected function rssTokenToName( $n ) { |
57 | | - switch( $n ) { |
| 77 | + protected function rssTokenToName( $name ) { |
| 78 | + switch( $name ) { |
58 | 79 | case 'dc:date': |
59 | 80 | case 'pubDate': |
| 81 | + case 'updated': |
60 | 82 | return 'date'; |
61 | 83 | case 'dc:creator': |
62 | 84 | return 'author'; |
— | — | @@ -73,9 +95,8 @@ |
74 | 96 | case 'comments': |
75 | 97 | case 'category': |
76 | 98 | return null; |
77 | | - |
78 | 99 | default: |
79 | | - return $n; |
| 100 | + return $name; |
80 | 101 | } |
81 | 102 | } |
82 | 103 | } |
\ No newline at end of file |
Index: trunk/extensions/RSS/RSSParser.php |
— | — | @@ -328,24 +328,32 @@ |
329 | 329 | |
330 | 330 | foreach ( array_keys( $item ) as $info ) { |
331 | 331 | switch ( $info ) { |
| 332 | + // ATOM <id> elements and RSS <link> elements are item link urls |
| 333 | + case 'id': |
| 334 | + $txt = $this->sanitizeUrl( $item['id'] ); |
| 335 | + $renderedItem = str_replace( '{{{link}}}', $txt, $renderedItem ); |
| 336 | + break; |
332 | 337 | case 'link': |
333 | | - $txt = $this->sanitizeUrl( $item[ $info ] ); |
| 338 | + if ( !isset( $item['id'] ) ) { |
| 339 | + $txt = $this->sanitizeUrl( $item['link'] ); |
| 340 | + } |
| 341 | + $renderedItem = str_replace( '{{{link}}}', $txt, $renderedItem ); |
334 | 342 | break; |
335 | 343 | case 'date': |
336 | 344 | $tempTimezone = date_default_timezone_get(); |
337 | 345 | date_default_timezone_set( 'UTC' ); |
338 | | - $txt = date( $this->date, strtotime( $this->escapeTemplateParameter( $item[ $info ] ) ) ); |
| 346 | + $txt = date( $this->date, strtotime( $this->escapeTemplateParameter( $item['date'] ) ) ); |
339 | 347 | date_default_timezone_set( $tempTimezone ); |
| 348 | + $renderedItem = str_replace( '{{{date}}}', $txt, $renderedItem ); |
340 | 349 | break; |
341 | 350 | default: |
342 | | - $str = $this->escapeTemplateParameter( $item[ $info ] ); |
| 351 | + $str = $this->escapeTemplateParameter( $item[$info] ); |
343 | 352 | if ( mb_strlen( $str ) > $this->ItemMaxLength ) { |
344 | 353 | $str = mb_substr( $str, 0, $this->ItemMaxLength ) . " ..."; |
345 | 354 | } |
346 | 355 | $txt = $this->highlightTerms( $str ); |
| 356 | + $renderedItem = str_replace( '{{{' . $info . '}}}', $txt, $renderedItem ); |
347 | 357 | } |
348 | | - |
349 | | - $renderedItem = str_replace( '{{{' . $info . '}}}', $txt, $renderedItem ); |
350 | 358 | } |
351 | 359 | |
352 | 360 | // nullify all remaining info items in the template |
Index: trunk/extensions/RSS/RSS.php |
— | — | @@ -4,7 +4,7 @@ |
5 | 5 | * |
6 | 6 | * @file |
7 | 7 | * @ingroup Extensions |
8 | | - * @version 1.94 |
| 8 | + * @version 2.00 |
9 | 9 | * @author mutante, Daniel Kinzler, Rdb, Mafs, Thomas Gries, Alxndr, Chris Reigrut, K001 |
10 | 10 | * @author Kellan Elliott-McCrea <kellan@protest.net> -- author of MagpieRSS |
11 | 11 | * @author Jeroen De Dauw |
— | — | @@ -14,7 +14,7 @@ |
15 | 15 | * @link http://www.mediawiki.org/wiki/Extension:RSS Documentation |
16 | 16 | */ |
17 | 17 | |
18 | | -define( "EXTENSION_RSS_VERSION", "1.94 20120223" ); |
| 18 | +define( "EXTENSION_RSS_VERSION", "2.00 20120224" ); |
19 | 19 | |
20 | 20 | if ( !defined( 'MEDIAWIKI' ) ) { |
21 | 21 | die( "This is not a valid entry point.\n" ); |
— | — | @@ -49,6 +49,7 @@ |
50 | 50 | // Check cached content, if available, against remote. |
51 | 51 | // $wgRSSCacheCompare should be set to false or a timeout |
52 | 52 | // (less than $wgRSSCacheAge) after which a comparison will be made. |
| 53 | +// for debugging set $wgRSSCacheCompare = 1; |
53 | 54 | $wgRSSCacheCompare = false; |
54 | 55 | |
55 | 56 | // 5 second timeout |