PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/extensions/SemanticMediaWiki/includes/queryprinters/SMW_QP_RSSlink.php

https://github.com/ChuguluGames/mediawiki-svn
PHP | 253 lines | 191 code | 25 blank | 37 comment | 43 complexity | e0462bc2a2b991802d5899b831517033 MD5 | raw file
  1. <?php
  2. /**
  3. * Print links to RSS feeds for query results.
  4. * @file
  5. * @ingroup SMWQuery
  6. */
  7. /**
  8. * Printer for creating a link to RSS feeds.
  9. *
  10. * @author Denny Vrandecic
  11. * @author Markus Krötzsch
  12. * @ingroup SMWQuery
  13. */
  14. class SMWRSSResultPrinter extends SMWResultPrinter {
  15. protected $m_title = '';
  16. protected $m_description = '';
  17. protected function readParameters( $params, $outputmode ) {
  18. parent::readParameters( $params, $outputmode );
  19. if ( array_key_exists( 'title', $this->m_params ) ) {
  20. $this->m_title = trim( $this->m_params['title'] );
  21. // for backward compatibiliy
  22. } elseif ( array_key_exists( 'rsstitle', $this->m_params ) ) {
  23. $this->m_title = trim( $this->m_params['rsstitle'] );
  24. }
  25. if ( array_key_exists( 'description', $this->m_params ) ) {
  26. $this->m_description = trim( $this->m_params['description'] );
  27. // for backward compatibiliy
  28. } elseif ( array_key_exists( 'rssdescription', $this->m_params ) ) {
  29. $this->m_description = trim( $this->m_params['rssdescription'] );
  30. }
  31. }
  32. public function getMimeType( $res ) {
  33. return 'application/rss+xml'; // or is rdf+xml better? Might be confused in either case (with RSS2.0 or RDF)
  34. }
  35. public function getQueryMode( $context ) {
  36. return ( $context == SMWQueryProcessor::SPECIAL_PAGE ) ? SMWQuery::MODE_INSTANCES:SMWQuery::MODE_NONE;
  37. }
  38. public function getName() {
  39. smwfLoadExtensionMessages( 'SemanticMediaWiki' );
  40. return wfMsg( 'smw_printername_rss' );
  41. }
  42. protected function getResultText( SMWQueryResult $res, $outputmode ) {
  43. global $smwgIQRunningNumber, $wgSitename, $wgServer, $smwgRSSEnabled, $wgRequest;
  44. $result = '';
  45. if ( $outputmode == SMW_OUTPUT_FILE ) { // make RSS feed
  46. if ( !$smwgRSSEnabled ) return '';
  47. if ( $this->m_title == '' ) {
  48. $this->m_title = $wgSitename;
  49. }
  50. if ( $this->m_description == '' ) {
  51. smwfLoadExtensionMessages( 'SemanticMediaWiki' );
  52. $this->m_description = wfMsg( 'smw_rss_description', $wgSitename );
  53. }
  54. // cast printouts into "items"
  55. $items = array();
  56. $row = $res->getNext();
  57. while ( $row !== false ) {
  58. $creators = array();
  59. $dates = array();
  60. $wikipage = $row[0]->getNextDataValue(); // get the object
  61. foreach ( $row as $field ) {
  62. // for now we ignore everything but creator and date, later we may
  63. // add more things like geolocs, categories, and even a generic
  64. // mechanism to add whatever you want :)
  65. $req = $field->getPrintRequest();
  66. if ( strtolower( $req->getLabel() ) == 'creator' ) {
  67. foreach ( $field->getContent() as $entry ) {
  68. $creators[] = $entry->getShortWikiText();
  69. }
  70. } elseif ( ( strtolower( $req->getLabel() ) == 'date' ) && ( $req->getTypeID() == '_dat' ) ) {
  71. foreach ( $field->getContent() as $entry ) {
  72. $dates[] = $entry->getXMLSchemaDate();
  73. }
  74. }
  75. }
  76. if ( $wikipage instanceof SMWWikiPageValue ) { // this should rarely fail, but better be carful
  77. ///TODO: It would be more elegant to have type chekcs initially
  78. $items[] = new SMWRSSItem( $wikipage->getTitle(), $creators, $dates );
  79. }
  80. $row = $res->getNext();
  81. }
  82. $result .= '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
  83. $result .= "<rdf:RDF\n";
  84. $result .= "\txmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n";
  85. $result .= "\txmlns:content=\"http://purl.org/rss/1.0/modules/content/\"\n";
  86. $result .= "\txmlns:admin=\"http://webns.net/mvcb/\"\n";
  87. $result .= "\txmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n";
  88. $result .= "\txmlns=\"http://purl.org/rss/1.0/\">\n";
  89. $result .= "\t<channel rdf:about=\"" . str_replace( '&', '&amp;', $wgRequest->getFullRequestURL() ) . "\">\n";
  90. $result .= "\t\t<admin:generatorAgent rdf:resource=\"http://semantic-mediawiki.org/wiki/Special:URIResolver/Semantic_MediaWiki\"/>\n";
  91. $result .= "\t\t<title>" . smwfXMLContentEncode( $this->m_title ) . "</title>\n";
  92. $result .= "\t\t<link>$wgServer</link>\n";
  93. $result .= "\t\t<description>" . smwfXMLContentEncode( $this->m_description ) . "</description>\n";
  94. if ( count( $items ) > 0 ) {
  95. $result .= "\t\t<items>\n";
  96. $result .= "\t\t\t<rdf:Seq>\n";
  97. foreach ( $items as $item ) {
  98. $result .= "\t\t\t\t<rdf:li rdf:resource=\"" . $item->uri() . "\"/>\n";
  99. }
  100. $result .= "\t\t\t</rdf:Seq>\n";
  101. $result .= "\t\t</items>\n";
  102. }
  103. $result .= "\t</channel>\n";
  104. foreach ( $items as $item ) {
  105. $result .= $item->text();
  106. }
  107. $result .= '</rdf:RDF>';
  108. } else { // just make link to feed
  109. if ( $this->getSearchLabel( $outputmode ) ) {
  110. $label = $this->getSearchLabel( $outputmode );
  111. } else {
  112. smwfLoadExtensionMessages( 'SemanticMediaWiki' );
  113. $label = wfMsgForContent( 'smw_rss_link' );
  114. }
  115. $link = $res->getQueryLink( $label );
  116. $link->setParameter( 'rss', 'format' );
  117. if ( $this->m_title !== '' ) {
  118. $link->setParameter( $this->m_title, 'title' );
  119. }
  120. if ( $this->m_description !== '' ) {
  121. $link->setParameter( $this->m_description, 'description' );
  122. }
  123. if ( array_key_exists( 'limit', $this->m_params ) ) {
  124. $link->setParameter( $this->m_params['limit'], 'limit' );
  125. } else { // use a reasonable deafult limit (10 is suggested by RSS)
  126. $link->setParameter( 10, 'limit' );
  127. }
  128. foreach ( $res->getPrintRequests() as $printout ) { // overwrite given "sort" parameter with printout of label "date"
  129. if ( ( $printout->getMode() == SMWPrintRequest::PRINT_PROP ) && ( strtolower( $printout->getLabel() ) == "date" ) && ( $printout->getTypeID() == "_dat" ) ) {
  130. $link->setParameter( $printout->getData()->getWikiValue(), 'sort' );
  131. }
  132. }
  133. $result .= $link->getText( $outputmode, $this->mLinker );
  134. $this->isHTML = ( $outputmode == SMW_OUTPUT_HTML ); // yes, our code can be viewed as HTML if requested, no more parsing needed
  135. SMWOutputs::requireHeadItem( 'rss' . $smwgIQRunningNumber, '<link rel="alternate" type="application/rss+xml" title="' . $this->m_title . '" href="' . $link->getURL() . '" />' );
  136. }
  137. return $result;
  138. }
  139. public function getParameters() {
  140. $params = array_merge( parent::getParameters(), $this->exportFormatParameters() );
  141. $params['title'] = new Parameter( 'title' );
  142. $params['title']->setMessage( 'smw_paramdesc_rsstitle' );
  143. $params['description'] = new Parameter( 'title' );
  144. $params['description']->setMessage( 'smw_paramdesc_rssdescription' );
  145. return $params;
  146. }
  147. }
  148. /**
  149. * Represents a single entry, or item, in an RSS feed. Useful since those items are iterated more
  150. * than once when serialising RSS.
  151. * @todo This code still needs cleanup, it's a mess.
  152. * @ingroup SMWQuery
  153. */
  154. class SMWRSSItem {
  155. private $uri;
  156. private $label;
  157. private $creator;
  158. private $date;
  159. private $articlename;
  160. private $title;
  161. /**
  162. * Constructor for a single item in the feed. Requires the URI of the item.
  163. */
  164. public function __construct( Title $t, $c, $d ) {
  165. $this->title = $t;
  166. $this->uri = $t->getFullURL();
  167. $this->label = $t->getText();
  168. $article = null;
  169. if ( count( $c ) == 0 ) {
  170. $article = new Article( $t );
  171. $this->creator = array();
  172. $this->creator[] = $article->getUserText();
  173. } else {
  174. $this->creator = $c;
  175. }
  176. $this->date = array();
  177. if ( count( $d ) == 0 ) {
  178. if ( $article === null ) {
  179. $article = new Article( $t );
  180. }
  181. $this->date[] = date( "c", strtotime( $article->getTimestamp() ) );
  182. } else {
  183. foreach ( $d as $date ) {
  184. $this->date[] = $date;
  185. }
  186. }
  187. // get content
  188. if ( $t->getNamespace() == NS_MAIN ) {
  189. $this->articlename = ':' . $t->getDBkey();
  190. } else {
  191. $this->articlename = $t->getPrefixedDBKey();
  192. }
  193. }
  194. /**
  195. * Get function for the Item URI
  196. */
  197. public function uri() {
  198. return $this->uri;
  199. }
  200. /**
  201. * Creates the RSS output for the single item.
  202. */
  203. public function text() {
  204. global $wgServer, $wgParser, $smwgShowFactbox, $smwgRSSWithPages;
  205. static $parser_options = null;
  206. $smwgShowFactbox = SMW_FACTBOX_HIDDEN; // just hide factbox; no need to restore this setting, I hope that nothing comes after FILE outputs
  207. $text = "\t<item rdf:about=\"$this->uri\">\n";
  208. $text .= "\t\t<title>" . smwfXMLContentEncode( $this->label ) . "</title>\n";
  209. $text .= "\t\t<link>" . smwfXMLContentEncode( $this->uri ) . "</link>\n";
  210. foreach ( $this->date as $date )
  211. $text .= "\t\t<dc:date>$date</dc:date>\n";
  212. foreach ( $this->creator as $creator )
  213. $text .= "\t\t<dc:creator>" . smwfXMLContentEncode( $creator ) . "</dc:creator>\n";
  214. if ( $smwgRSSWithPages ) {
  215. $parser_options = new ParserOptions();
  216. $parser_options->setEditSection( false ); // embedded sections should not have edit links
  217. $parserOutput = $wgParser->parse( '{{' . $this->articlename . '}}', $this->title, $parser_options );
  218. $content = $parserOutput->getText();
  219. // Make absolute URLs out of the local ones:
  220. ///TODO is there maybe a way in the parser options to make the URLs absolute?
  221. $content = str_replace( '<a href="/', '<a href="' . $wgServer . '/', $content );
  222. $text .= "\t\t<description>" . smwfXMLContentEncode( $content ) . "</description>\n";
  223. $text .= "\t\t<content:encoded rdf:datatype=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral\"><![CDATA[$content]]></content:encoded>\n";
  224. }
  225. $text .= "\t</item>\n";
  226. return $text;
  227. }
  228. }