PageRenderTime 29ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/extensions/SemanticResultFormats/iCalendar/SRF_iCalendar.php

https://github.com/ChuguluGames/mediawiki-svn
PHP | 269 lines | 163 code | 49 blank | 57 comment | 58 complexity | c77d1ba13ed3b56c5df15251deade2ba MD5 | raw file
  1. <?php
  2. /**
  3. * Create iCalendar exports
  4. * @file
  5. * @ingroup SemanticResultFormats
  6. */
  7. /**
  8. * Printer class for creating iCalendar exports
  9. *
  10. * @author Markus Krötzsch
  11. * @author Denny Vrandecic
  12. * @author Jeroen De Dauw
  13. *
  14. * @ingroup SemanticResultFormats
  15. */
  16. class SRFiCalendar extends SMWResultPrinter {
  17. protected $m_title = '';
  18. protected $m_description = '';
  19. protected function readParameters( $params, $outputmode ) {
  20. parent::readParameters( $params, $outputmode );
  21. if ( array_key_exists( 'title', $this->m_params ) ) {
  22. $this->m_title = trim( $this->m_params['title'] );
  23. // for backward compatibility
  24. } elseif ( array_key_exists( 'icalendartitle', $this->m_params ) ) {
  25. $this->m_title = trim( $this->m_params['icalendartitle'] );
  26. }
  27. if ( array_key_exists( 'description', $this->m_params ) ) {
  28. $this->m_description = trim( $this->m_params['description'] );
  29. // for backward compatibility
  30. } elseif ( array_key_exists( 'icalendardescription', $this->m_params ) ) {
  31. $this->m_description = trim( $this->m_params['icalendardescription'] );
  32. }
  33. }
  34. public function getMimeType( $res ) {
  35. return 'text/calendar';
  36. }
  37. public function getFileName( $res ) {
  38. if ( $this->m_title != '' ) {
  39. return str_replace( ' ', '_', $this->m_title ) . '.ics';
  40. } else {
  41. return 'iCalendar.ics';
  42. }
  43. }
  44. public function getQueryMode( $context ) {
  45. return ( $context == SMWQueryProcessor::SPECIAL_PAGE ) ? SMWQuery::MODE_INSTANCES : SMWQuery::MODE_NONE;
  46. }
  47. public function getName() {
  48. return wfMsg( 'srf_printername_icalendar' );
  49. }
  50. protected function getResultText( SMWQueryResult $res, $outputmode ) {
  51. return $outputmode == SMW_OUTPUT_FILE ? $this->getIcal( $res ) : $this->getIcalLink( $res, $outputmode );
  52. }
  53. /**
  54. * Returns the query result in iCal.
  55. *
  56. * @since 1.5.2
  57. *
  58. * @param SMWQueryResult $res
  59. *
  60. * @return string
  61. */
  62. protected function getIcal( SMWQueryResult $res ) {
  63. $result = '';
  64. if ( $this->m_title == '' ) {
  65. global $wgSitename;
  66. $this->m_title = $wgSitename;
  67. }
  68. $result .= "BEGIN:VCALENDAR\r\n";
  69. $result .= "PRODID:-//SMW Project//Semantic Result Formats\r\n";
  70. $result .= "VERSION:2.0\r\n";
  71. $result .= "METHOD:PUBLISH\r\n";
  72. $result .= "X-WR-CALNAME:" . $this->m_title . "\r\n";
  73. if ( $this->m_description !== '' ) {
  74. $result .= "X-WR-CALDESC:" . $this->m_description . "\r\n";
  75. }
  76. // TODO: http://www.kanzaki.com/docs/ical/vtimezone.html
  77. // $result .= "BEGIN:VTIMEZONE\r\n";
  78. // $result .= "TZID:\r\n";
  79. $row = $res->getNext();
  80. while ( $row !== false ) {
  81. $result .= $this->getIcalForItem( $row );
  82. $row = $res->getNext();
  83. }
  84. // $result .= "END:VTIMEZONE\r\n";
  85. $result .= "END:VCALENDAR\r\n";
  86. return $result;
  87. }
  88. /**
  89. * Returns html for a link to a query that returns the iCal.
  90. *
  91. * @since 1.5.2
  92. *
  93. * @param SMWQueryResult $res
  94. * @param $outputmode
  95. *
  96. * @return string
  97. */
  98. protected function getIcalLink( SMWQueryResult $res, $outputmode ) {
  99. if ( $this->getSearchLabel( $outputmode ) ) {
  100. $label = $this->getSearchLabel( $outputmode );
  101. } else {
  102. $label = wfMsgForContent( 'srf_icalendar_link' );
  103. }
  104. $link = $res->getQueryLink( $label );
  105. $link->setParameter( 'icalendar', 'format' );
  106. if ( $this->m_title !== '' ) {
  107. $link->setParameter( $this->m_title, 'title' );
  108. }
  109. if ( $this->m_description !== '' ) {
  110. $link->setParameter( $this->m_description, 'description' );
  111. }
  112. if ( array_key_exists( 'limit', $this->m_params ) ) {
  113. $link->setParameter( $this->m_params['limit'], 'limit' );
  114. } else { // use a reasonable default limit
  115. $link->setParameter( 20, 'limit' );
  116. }
  117. // yes, our code can be viewed as HTML if requested, no more parsing needed
  118. $this->isHTML = ( $outputmode == SMW_OUTPUT_HTML );
  119. return $link->getText( $outputmode, $this->mLinker );
  120. }
  121. /**
  122. * Returns the iCal for a single item.
  123. *
  124. * @since 1.5.2
  125. *
  126. * @param array $row
  127. *
  128. * @return string
  129. */
  130. protected function getIcalForItem( array $row ) {
  131. $result = '';
  132. $wikipage = $row[0]->getResultSubject(); // get the object
  133. // As of SMW 1.6, a SMWDiWikiPage object will be provided instead of a SMWWikiPageValue.
  134. if ( class_exists( 'SMWDiWikiPage' ) && $wikipage instanceof SMWDiWikiPage ) {
  135. $wikipage = SMWDataValueFactory::newDataItemValue( $wikipage, null );
  136. }
  137. $startdate = false;
  138. $enddate = false;
  139. $location = '';
  140. $description = '';
  141. foreach ( $row as /* SMWResultArray */ $field ) {
  142. // later we may add more things like a generic
  143. // mechanism to add whatever you want :)
  144. // could include funny things like geo, description etc. though
  145. $req = $field->getPrintRequest();
  146. $label = strtolower( $req->getLabel() );
  147. if ( $label == 'start' && $req->getTypeID() == '_dat' ) {
  148. $startdate = efSRFGetNextDV( $field ); // save only the first
  149. }
  150. else if ( $label == 'end' && $req->getTypeID() == '_dat' ) {
  151. $enddate = efSRFGetNextDV( $field ); // save only the first
  152. }
  153. else if ( $label == 'location' ) {
  154. $value = efSRFGetNextDV( $field ); // save only the first
  155. if ( $value !== false ) {
  156. $location = $value->getShortWikiText();
  157. }
  158. }
  159. else if ( $label == 'description' ) {
  160. $value = efSRFGetNextDV( $field ); // save only the first
  161. if ( $value !== false ) {
  162. $description = $value->getShortWikiText();
  163. }
  164. }
  165. }
  166. $title = $wikipage->getTitle();
  167. $article = new Article( $title );
  168. $url = $title->getFullURL();
  169. $result .= "BEGIN:VEVENT\r\n";
  170. $result .= "SUMMARY:" . $wikipage->getShortWikiText() . "\r\n";
  171. $result .= "URL:$url\r\n";
  172. $result .= "UID:$url\r\n";
  173. if ( $startdate != false ) $result .= "DTSTART:" . $this->parsedate( $startdate ) . "\r\n";
  174. if ( $enddate != false ) $result .= "DTEND:" . $this->parsedate( $enddate, true ) . "\r\n";
  175. if ( $location != "" ) $result .= "LOCATION:$location\r\n";
  176. if ( $description != "" ) $result .= "DESCRIPTION:$description\r\n";
  177. $t = strtotime( str_replace( 'T', ' ', $article->getTimestamp() ) );
  178. $result .= "DTSTAMP:" . date( "Ymd", $t ) . "T" . date( "His", $t ) . "\r\n";
  179. $result .= "SEQUENCE:" . $title->getLatestRevID() . "\r\n";
  180. $result .= "END:VEVENT\r\n";
  181. return $result;
  182. }
  183. /**
  184. * Extract a date string formatted for iCalendar from a SMWTimeValue object.
  185. */
  186. static private function parsedate( SMWTimeValue $dv, $isend = false ) {
  187. $year = $dv->getYear();
  188. if ( ( $year > 9999 ) || ( $year < - 9998 ) ) return ''; // ISO range is limited to four digits
  189. $year = number_format( $year, 0, '.', '' );
  190. $time = str_replace( ':', '', $dv->getTimeString( false ) );
  191. if ( ( $time == false ) && ( $isend ) ) { // increment by one day, compute date to cover leap years etc.
  192. $dv = SMWDataValueFactory::newTypeIDValue( '_dat', $dv->getWikiValue() . 'T00:00:00-24:00' );
  193. }
  194. $month = $dv->getMonth();
  195. if ( strlen( $month ) == 1 ) $month = '0' . $month;
  196. $day = $dv->getDay();
  197. if ( strlen( $day ) == 1 ) $day = '0' . $day;
  198. $result = $year . $month . $day;
  199. if ( $time != false ) $result .= "T$time";
  200. return $result;
  201. }
  202. public function getParameters() {
  203. if ( defined( 'SMW_SUPPORTS_VALIDATOR' ) ) {
  204. $params = array_merge( parent::getParameters(), $this->exportFormatParameters() );
  205. $params['title'] = new Parameter( 'title' );
  206. $params['title']->setDescription( wfMsg( 'srf_paramdesc_icalendartitle' ) );
  207. $params['title']->setDefault( '' );
  208. $params['description'] = new Parameter( 'description' );
  209. $params['description']->setDescription( wfMsg( 'srf_paramdesc_icalendardescription' ) );
  210. $params['description']->setDefault( '' );
  211. }
  212. else {
  213. // This if for b/c with SMW 1.5.x; SMW 1.6 directly accepts Parameter objects.
  214. $params = parent::exportFormatParameters();
  215. $params[] = array( 'name' => 'title', 'type' => 'string', 'description' => wfMsg( 'srf_paramdesc_icalendartitle' ) );
  216. $params[] = array( 'name' => 'description', 'type' => 'string', 'description' => wfMsg( 'srf_paramdesc_icalendardescription' ) );
  217. }
  218. return $params;
  219. }
  220. }