Index: trunk/extensions/SemanticResultFormats/iCalendar/SRF_iCalendar.php |
— | — | @@ -7,8 +7,11 @@ |
8 | 8 | |
9 | 9 | /** |
10 | 10 | * Printer class for creating iCalendar exports |
| 11 | + * |
11 | 12 | * @author Markus Krötzsch |
12 | 13 | * @author Denny Vrandecic |
| 14 | + * @author Jeroen De Dauw |
| 15 | + * |
13 | 16 | * @ingroup SemanticResultFormats |
14 | 17 | */ |
15 | 18 | class SRFiCalendar extends SMWResultPrinter { |
— | — | @@ -17,12 +20,14 @@ |
18 | 21 | |
19 | 22 | protected function readParameters( $params, $outputmode ) { |
20 | 23 | SMWResultPrinter::readParameters( $params, $outputmode ); |
| 24 | + |
21 | 25 | if ( array_key_exists( 'title', $this->m_params ) ) { |
22 | 26 | $this->m_title = trim( $this->m_params['title'] ); |
23 | 27 | // for backward compatibility |
24 | 28 | } elseif ( array_key_exists( 'icalendartitle', $this->m_params ) ) { |
25 | 29 | $this->m_title = trim( $this->m_params['icalendartitle'] ); |
26 | 30 | } |
| 31 | + |
27 | 32 | if ( array_key_exists( 'description', $this->m_params ) ) { |
28 | 33 | $this->m_description = trim( $this->m_params['description'] ); |
29 | 34 | // for backward compatibility |
— | — | @@ -53,96 +58,156 @@ |
54 | 59 | } |
55 | 60 | |
56 | 61 | protected function getResultText( $res, $outputmode ) { |
57 | | - global $smwgIQRunningNumber, $wgSitename, $wgServer, $wgRequest; |
| 62 | + return $outputmode == SMW_OUTPUT_FILE ? $this->getIcal( $res ) : $this->getIcalLink( $res, $outputmode ); |
| 63 | + } |
| 64 | + |
| 65 | + /** |
| 66 | + * Returns the query result in iCal. |
| 67 | + * |
| 68 | + * @since 1.5.2 |
| 69 | + * |
| 70 | + * @param SMWQueryResult $res |
| 71 | + * |
| 72 | + * @return string |
| 73 | + */ |
| 74 | + protected function getIcal( SMWQueryResult $res ) { |
58 | 75 | $result = ''; |
| 76 | + |
| 77 | + if ( $this->m_title == '' ) { |
| 78 | + global $wgSitename; |
| 79 | + $this->m_title = $wgSitename; |
| 80 | + } |
| 81 | + |
| 82 | + $result .= "BEGIN:VCALENDAR\r\n"; |
| 83 | + $result .= "PRODID:-//SMW Project//Semantic Result Formats\r\n"; |
| 84 | + $result .= "VERSION:2.0\r\n"; |
| 85 | + $result .= "METHOD:PUBLISH\r\n"; |
| 86 | + $result .= "X-WR-CALNAME:" . $this->m_title . "\r\n"; |
| 87 | + |
| 88 | + if ( $this->m_description !== '' ) { |
| 89 | + $result .= "X-WR-CALDESC:" . $this->m_description . "\r\n"; |
| 90 | + } |
| 91 | + |
| 92 | + //$result .= "BEGIN:VTIMEZONE\r\n"; |
59 | 93 | |
60 | | - if ( $outputmode == SMW_OUTPUT_FILE ) { // make RSS feed |
61 | | - if ( $this->m_title == '' ) { |
62 | | - $this->m_title = $wgSitename; |
| 94 | + $row = $res->getNext(); |
| 95 | + while ( $row !== false ) { |
| 96 | + $result .= $this->getIcalForItem( $row ); |
| 97 | + $row = $res->getNext(); |
| 98 | + } |
| 99 | + |
| 100 | + //$result .= "END:VTIMEZONE\r\n"; |
| 101 | + |
| 102 | + $result .= "END:VCALENDAR\r\n"; |
| 103 | + |
| 104 | + return $result; |
| 105 | + } |
| 106 | + |
| 107 | + /** |
| 108 | + * Returns html for a link to a query that returns the iCal. |
| 109 | + * |
| 110 | + * @since 1.5.2 |
| 111 | + * |
| 112 | + * @param SMWQueryResult $res |
| 113 | + * @param $outputmode |
| 114 | + * |
| 115 | + * @return string |
| 116 | + */ |
| 117 | + protected function getIcalLink( SMWQueryResult $res, $outputmode ) { |
| 118 | + if ( $this->getSearchLabel( $outputmode ) ) { |
| 119 | + $label = $this->getSearchLabel( $outputmode ); |
| 120 | + } else { |
| 121 | + wfLoadExtensionMessages( 'SemanticResultFormats' ); |
| 122 | + $label = wfMsgForContent( 'srf_icalendar_link' ); |
| 123 | + } |
| 124 | + |
| 125 | + $link = $res->getQueryLink( $label ); |
| 126 | + $link->setParameter( 'icalendar', 'format' ); |
| 127 | + |
| 128 | + if ( $this->m_title !== '' ) { |
| 129 | + $link->setParameter( $this->m_title, 'title' ); |
| 130 | + } |
| 131 | + |
| 132 | + if ( $this->m_description !== '' ) { |
| 133 | + $link->setParameter( $this->m_description, 'description' ); |
| 134 | + } |
| 135 | + |
| 136 | + if ( array_key_exists( 'limit', $this->m_params ) ) { |
| 137 | + $link->setParameter( $this->m_params['limit'], 'limit' ); |
| 138 | + } else { // use a reasonable default limit |
| 139 | + $link->setParameter( 20, 'limit' ); |
| 140 | + } |
| 141 | + |
| 142 | + // yes, our code can be viewed as HTML if requested, no more parsing needed |
| 143 | + $this->isHTML = ( $outputmode == SMW_OUTPUT_HTML ); |
| 144 | + return $link->getText( $outputmode, $this->mLinker ); |
| 145 | + } |
| 146 | + |
| 147 | + /** |
| 148 | + * Returns the iCal for a single item. |
| 149 | + * |
| 150 | + * @since 1.5.2 |
| 151 | + * |
| 152 | + * @param array $row |
| 153 | + * |
| 154 | + * @return string |
| 155 | + */ |
| 156 | + protected function getIcalForItem( array $row ) { |
| 157 | + $result = ''; |
| 158 | + |
| 159 | + $wikipage = $row[0]->getResultSubject(); // get the object |
| 160 | + $startdate = false; |
| 161 | + $enddate = false; |
| 162 | + $location = ''; |
| 163 | + $description = ''; |
| 164 | + |
| 165 | + foreach ( $row as $field ) { |
| 166 | + // later we may add more things like a generic |
| 167 | + // mechanism to add whatever you want :) |
| 168 | + // could include funny things like geo, description etc. though |
| 169 | + $req = $field->getPrintRequest(); |
| 170 | + if ( ( strtolower( $req->getLabel() ) == "start" ) && ( $req->getTypeID() == "_dat" ) ) { |
| 171 | + $startdate = current( $field->getContent() ); // save only the first |
63 | 172 | } |
64 | | - $result .= "BEGIN:VCALENDAR\r\n"; |
65 | | - $result .= "PRODID:-//SMW Project//Semantic Result Formats\r\n"; |
66 | | - $result .= "VERSION:2.0\r\n"; |
67 | | - $result .= "METHOD:PUBLISH\r\n"; |
68 | | - $result .= "X-WR-CALNAME:" . $this->m_title . "\r\n"; |
69 | | - if ( $this->m_description !== '' ) { |
70 | | - $result .= "X-WR-CALDESC:" . $this->m_description . "\r\n"; |
| 173 | + |
| 174 | + if ( ( strtolower( $req->getLabel() ) == 'end' ) && ( $req->getTypeID() == '_dat' ) ) { |
| 175 | + $enddate = current( $field->getContent() ); // save only the first |
71 | 176 | } |
72 | | - |
73 | | - $row = $res->getNext(); |
74 | | - while ( $row !== false ) { |
75 | | - $wikipage = $row[0]->getResultSubject(); // get the object |
76 | | - $startdate = false; |
77 | | - $enddate = false; |
78 | | - $location = ''; |
79 | | - $description = ''; |
80 | | - foreach ( $row as $field ) { |
81 | | - // later we may add more things like a generic |
82 | | - // mechanism to add whatever you want :) |
83 | | - // could include funny things like geo, description etc. though |
84 | | - $req = $field->getPrintRequest(); |
85 | | - if ( ( strtolower( $req->getLabel() ) == "start" ) && ( $req->getTypeID() == "_dat" ) ) { |
86 | | - $startdate = current( $field->getContent() ); // save only the first |
87 | | - } |
88 | | - if ( ( strtolower( $req->getLabel() ) == "end" ) && ( $req->getTypeID() == "_dat" ) ) { |
89 | | - $enddate = current( $field->getContent() ); // save only the first |
90 | | - } |
91 | | - if ( strtolower( $req->getLabel() ) == "location" ) { |
92 | | - $value = current( $field->getContent() ); // save only the first |
93 | | - if ( $value !== false ) { |
94 | | - $location = $value->getShortWikiText(); |
95 | | - } |
96 | | - } |
97 | | - if ( strtolower( $req->getLabel() ) == "description" ) { |
98 | | - $value = current( $field->getContent() ); // save only the first |
99 | | - if ( $value !== false ) { |
100 | | - $description = $value->getShortWikiText(); |
101 | | - } |
102 | | - } |
| 177 | + |
| 178 | + if ( strtolower( $req->getLabel() ) == 'location' ) { |
| 179 | + $value = current( $field->getContent() ); // save only the first |
| 180 | + if ( $value !== false ) { |
| 181 | + $location = $value->getShortWikiText(); |
103 | 182 | } |
104 | | - $title = $wikipage->getTitle(); |
105 | | - $article = new Article( $title ); |
106 | | - $url = $title->getFullURL(); |
107 | | - $result .= "BEGIN:VEVENT\r\n"; |
108 | | - $result .= "SUMMARY:" . $wikipage->getShortWikiText() . "\r\n"; |
109 | | - $result .= "URL:$url\r\n"; |
110 | | - $result .= "UID:$url\r\n"; |
111 | | - if ( $startdate != false ) $result .= "DTSTART:" . $this->parsedate( $startdate ) . "\r\n"; |
112 | | - if ( $enddate != false ) $result .= "DTEND:" . $this->parsedate( $enddate, true ) . "\r\n"; |
113 | | - if ( $location != "" ) $result .= "LOCATION:$location\r\n"; |
114 | | - if ( $description != "" ) $result .= "DESCRIPTION:$description\r\n"; |
115 | | - $t = strtotime( str_replace( 'T', ' ', $article->getTimestamp() ) ); |
116 | | - $result .= "DTSTAMP:" . date( "Ymd", $t ) . "T" . date( "His", $t ) . "\r\n"; |
117 | | - $result .= "SEQUENCE:" . $title->getLatestRevID() . "\r\n"; |
118 | | - $result .= "END:VEVENT\r\n"; |
119 | | - $row = $res->getNext(); |
120 | 183 | } |
121 | | - $result .= "END:VCALENDAR\r\n"; |
122 | | - } else { // just make link to feed |
123 | | - if ( $this->getSearchLabel( $outputmode ) ) { |
124 | | - $label = $this->getSearchLabel( $outputmode ); |
125 | | - } else { |
126 | | - wfLoadExtensionMessages( 'SemanticResultFormats' ); |
127 | | - $label = wfMsgForContent( 'srf_icalendar_link' ); |
| 184 | + |
| 185 | + if ( strtolower( $req->getLabel() ) == 'description' ) { |
| 186 | + $value = current( $field->getContent() ); // save only the first |
| 187 | + if ( $value !== false ) { |
| 188 | + $description = $value->getShortWikiText(); |
| 189 | + } |
128 | 190 | } |
129 | | - $link = $res->getQueryLink( $label ); |
130 | | - $link->setParameter( 'icalendar', 'format' ); |
131 | | - if ( $this->m_title !== '' ) { |
132 | | - $link->setParameter( $this->m_title, 'title' ); |
133 | | - } |
134 | | - if ( $this->m_description !== '' ) { |
135 | | - $link->setParameter( $this->m_description, 'description' ); |
136 | | - } |
137 | | - if ( array_key_exists( 'limit', $this->m_params ) ) { |
138 | | - $link->setParameter( $this->m_params['limit'], 'limit' ); |
139 | | - } else { // use a reasonable default limit |
140 | | - $link->setParameter( 20, 'limit' ); |
141 | | - } |
142 | | - |
143 | | - $result .= $link->getText( $outputmode, $this->mLinker ); |
144 | | - $this->isHTML = ( $outputmode == SMW_OUTPUT_HTML ); // yes, our code can be viewed as HTML if requested, no more parsing needed |
145 | 191 | } |
146 | | - |
| 192 | + |
| 193 | + $title = $wikipage->getTitle(); |
| 194 | + $article = new Article( $title ); |
| 195 | + $url = $title->getFullURL(); |
| 196 | + |
| 197 | + $result .= "BEGIN:VEVENT\r\n"; |
| 198 | + $result .= "SUMMARY:" . $wikipage->getShortWikiText() . "\r\n"; |
| 199 | + $result .= "URL:$url\r\n"; |
| 200 | + $result .= "UID:$url\r\n"; |
| 201 | + |
| 202 | + if ( $startdate != false ) $result .= "DTSTART:" . $this->parsedate( $startdate ) . "\r\n"; |
| 203 | + if ( $enddate != false ) $result .= "DTEND:" . $this->parsedate( $enddate, true ) . "\r\n"; |
| 204 | + if ( $location != "" ) $result .= "LOCATION:$location\r\n"; |
| 205 | + if ( $description != "" ) $result .= "DESCRIPTION:$description\r\n"; |
| 206 | + |
| 207 | + $t = strtotime( str_replace( 'T', ' ', $article->getTimestamp() ) ); |
| 208 | + $result .= "DTSTAMP:" . date( "Ymd", $t ) . "T" . date( "His", $t ) . "\r\n"; |
| 209 | + $result .= "SEQUENCE:" . $title->getLatestRevID() . "\r\n"; |
| 210 | + $result .= "END:VEVENT\r\n"; |
| 211 | + |
147 | 212 | return $result; |
148 | 213 | } |
149 | 214 | |
— | — | @@ -152,26 +217,34 @@ |
153 | 218 | static private function parsedate( SMWTimeValue $dv, $isend = false ) { |
154 | 219 | $year = $dv->getYear(); |
155 | 220 | if ( ( $year > 9999 ) || ( $year < - 9998 ) ) return ''; // ISO range is limited to four digits |
| 221 | + |
156 | 222 | $year = number_format( $year, 0, '.', '' ); |
157 | 223 | $time = str_replace( ':', '', $dv->getTimeString( false ) ); |
| 224 | + |
158 | 225 | if ( ( $time == false ) && ( $isend ) ) { // increment by one day, compute date to cover leap years etc. |
159 | 226 | $dv = SMWDataValueFactory::newTypeIDValue( '_dat', $dv->getWikiValue() . 'T00:00:00-24:00' ); |
160 | 227 | } |
| 228 | + |
161 | 229 | $month = $dv->getMonth(); |
162 | 230 | if ( strlen( $month ) == 1 ) $month = '0' . $month; |
| 231 | + |
163 | 232 | $day = $dv->getDay(); |
164 | 233 | if ( strlen( $day ) == 1 ) $day = '0' . $day; |
| 234 | + |
165 | 235 | $result = $year . $month . $day; |
| 236 | + |
166 | 237 | if ( $time != false ) $result .= "T$time"; |
| 238 | + |
167 | 239 | return $result; |
168 | 240 | } |
169 | 241 | |
170 | 242 | public function getParameters() { |
171 | 243 | $params = parent::exportFormatParameters(); |
| 244 | + |
172 | 245 | $params[] = array( 'name' => 'icalendartitle', 'type' => 'string', 'description' => wfMsg( 'srf_paramdesc_icalendartitle' ) ); |
173 | 246 | $params[] = array( 'name' => 'icalendardescription', 'type' => 'string', 'description' => wfMsg( 'srf_paramdesc_icalendardescription' ) ); |
| 247 | + |
174 | 248 | return $params; |
175 | 249 | } |
176 | 250 | |
177 | 251 | } |
178 | | - |