These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace SRF\iCalendar; |
||
4 | |||
5 | use SMW\Query\Result\ResultArray; |
||
6 | use SMWDataValueFactory as DataValueFactory; |
||
7 | use SMWExportPrinter as FileExportPrinter; |
||
8 | use SMWQuery as Query; |
||
9 | use SMWQueryProcessor as QueryProcessor; |
||
10 | use SMWQueryResult as QueryResult; |
||
11 | use SMWTimeValue as TimeValue; |
||
12 | use WikiPage; |
||
13 | |||
14 | /** |
||
15 | * Printer class for iCalendar exports |
||
16 | * |
||
17 | * @see https://en.wikipedia.org/wiki/ICalendar |
||
18 | * @see https://tools.ietf.org/html/rfc5545 |
||
19 | * |
||
20 | * @license GNU GPL v2+ |
||
21 | * @since 1.5 |
||
22 | * |
||
23 | * @author Markus Krötzsch |
||
24 | * @author Denny Vrandecic |
||
25 | * @author Jeroen De Dauw |
||
26 | */ |
||
27 | class iCalendarFileExportPrinter extends FileExportPrinter { |
||
28 | |||
29 | /** |
||
30 | * @var string |
||
31 | */ |
||
32 | private $title; |
||
33 | |||
34 | /** |
||
35 | * @var string |
||
36 | */ |
||
37 | private $description; |
||
38 | |||
39 | /** |
||
40 | * @var IcalTimezoneFormatter |
||
41 | */ |
||
42 | private $icalTimezoneFormatter; |
||
43 | |||
44 | /** |
||
45 | * @var DateParser |
||
46 | */ |
||
47 | private $dateParser; |
||
48 | |||
49 | /** |
||
50 | * @see ResultPrinter::getName |
||
51 | * |
||
52 | * @since 1.8 |
||
53 | * |
||
54 | * {@inheritDoc} |
||
55 | */ |
||
56 | public function getName() { |
||
57 | return wfMessage( 'srf_printername_icalendar' )->text(); |
||
58 | } |
||
59 | |||
60 | /** |
||
61 | * @see FileExportPrinter::getMimeType |
||
62 | * |
||
63 | * @since 1.8 |
||
64 | * |
||
65 | * {@inheritDoc} |
||
66 | */ |
||
67 | public function getMimeType( QueryResult $queryResult ) { |
||
68 | return 'text/calendar'; |
||
69 | } |
||
70 | |||
71 | /** |
||
72 | * @see FileExportPrinter::getFileName |
||
73 | * |
||
74 | * @since 1.8 |
||
75 | * |
||
76 | * {@inheritDoc} |
||
77 | */ |
||
78 | 3 | public function getFileName( QueryResult $queryResult ) { |
|
79 | |||
80 | 3 | if ( $this->title != '' ) { |
|
81 | 3 | return str_replace( ' ', '_', $this->title ) . '.ics'; |
|
82 | } |
||
83 | |||
84 | return 'iCalendar.ics'; |
||
85 | } |
||
86 | |||
87 | /** |
||
88 | * @see FileExportPrinter::getQueryMode |
||
89 | * |
||
90 | * @since 1.8 |
||
91 | * |
||
92 | * {@inheritDoc} |
||
93 | */ |
||
94 | 3 | public function getQueryMode( $context ) { |
|
95 | 3 | return ( $context == QueryProcessor::SPECIAL_PAGE ) ? Query::MODE_INSTANCES : Query::MODE_NONE; |
|
96 | } |
||
97 | |||
98 | /** |
||
99 | * @see ResultPrinter::getParamDefinitions |
||
100 | * |
||
101 | * @since 1.8 |
||
102 | * |
||
103 | * {@inheritDoc} |
||
104 | */ |
||
105 | 3 | public function getParamDefinitions( array $definitions ) { |
|
106 | 3 | $params = parent::getParamDefinitions( $definitions ); |
|
107 | |||
108 | 3 | $params['title'] = [ |
|
109 | 'default' => '', |
||
110 | 'message' => 'srf_paramdesc_icalendartitle', |
||
111 | ]; |
||
112 | |||
113 | 3 | $params['description'] = [ |
|
114 | 'default' => '', |
||
115 | 'message' => 'srf_paramdesc_icalendardescription', |
||
116 | ]; |
||
117 | |||
118 | 3 | $params['timezone'] = [ |
|
119 | 'default' => '', |
||
120 | 'message' => 'srf-paramdesc-icalendar-timezone', |
||
121 | ]; |
||
122 | |||
123 | 3 | return $params; |
|
124 | } |
||
125 | |||
126 | /** |
||
127 | * @see ResultPrinter::handleParameters |
||
128 | * |
||
129 | * {@inheritDoc} |
||
130 | */ |
||
131 | 3 | protected function handleParameters( array $params, $outputMode ) { |
|
132 | 3 | parent::handleParameters( $params, $outputMode ); |
|
133 | |||
134 | 3 | $this->title = trim( $params['title'] ); |
|
135 | 3 | $this->description = trim( $params['description'] ); |
|
136 | 3 | } |
|
137 | |||
138 | /** |
||
139 | * @see ResultPrinter::getResultText |
||
140 | * |
||
141 | * {@inheritDoc} |
||
142 | */ |
||
143 | 3 | protected function getResultText( QueryResult $res, $outputMode ) { |
|
144 | |||
145 | 3 | if ( $outputMode == SMW_OUTPUT_FILE ) { |
|
146 | 3 | return $this->getIcal( $res ); |
|
147 | } |
||
148 | |||
149 | return $this->getIcalLink( $res, $outputMode ); |
||
150 | } |
||
151 | |||
152 | /** |
||
153 | * Returns the query result in iCal. |
||
154 | */ |
||
155 | 3 | private function getIcal( QueryResult $res ) { |
|
156 | |||
157 | 3 | if ( $this->title == '' ) { |
|
158 | 3 | $this->title = $GLOBALS['wgSitename']; |
|
159 | } |
||
160 | |||
161 | 3 | $this->dateParser = new DateParser(); |
|
162 | |||
163 | 3 | $this->icalTimezoneFormatter = new IcalTimezoneFormatter(); |
|
164 | |||
165 | 3 | $this->icalTimezoneFormatter->setLocalTimezones( |
|
166 | 3 | $this->params['timezone'] ?? [] |
|
167 | ); |
||
168 | |||
169 | 3 | $icalFormatter = new IcalFormatter( |
|
170 | 3 | $this->icalTimezoneFormatter |
|
171 | ); |
||
172 | |||
173 | 3 | $icalFormatter->setCalendarName( |
|
174 | 3 | $this->title |
|
175 | ); |
||
176 | |||
177 | 3 | $icalFormatter->setDescription( |
|
178 | 3 | $this->description |
|
179 | ); |
||
180 | |||
181 | 3 | while ( $row = $res->getNext() ) { |
|
182 | 3 | $icalFormatter->addEvent( $this->getEventParams( $row ) ); |
|
183 | } |
||
184 | |||
185 | 3 | return $icalFormatter->getIcal(); |
|
186 | } |
||
187 | |||
188 | /** |
||
189 | * Returns html for a link to a query that returns the iCal. |
||
190 | */ |
||
191 | private function getIcalLink( QueryResult $res, $outputMode ) { |
||
192 | |||
193 | if ( $this->getSearchLabel( $outputMode ) ) { |
||
194 | $label = $this->getSearchLabel( $outputMode ); |
||
195 | } else { |
||
196 | $label = wfMessage( 'srf_icalendar_link' )->inContentLanguage()->text(); |
||
197 | } |
||
198 | |||
199 | $link = $res->getQueryLink( $label ); |
||
200 | $link->setParameter( 'icalendar', 'format' ); |
||
201 | |||
202 | if ( $this->title !== '' ) { |
||
203 | $link->setParameter( $this->title, 'title' ); |
||
204 | } |
||
205 | |||
206 | if ( $this->description !== '' ) { |
||
207 | $link->setParameter( $this->description, 'description' ); |
||
208 | } |
||
209 | |||
210 | if ( array_key_exists( 'limit', $this->params ) ) { |
||
211 | $link->setParameter( $this->params['limit'], 'limit' ); |
||
212 | } else { // use a reasonable default limit |
||
213 | $link->setParameter( 20, 'limit' ); |
||
214 | } |
||
215 | |||
216 | // yes, our code can be viewed as HTML if requested, no more parsing needed |
||
217 | $this->isHTML = ( $outputMode == SMW_OUTPUT_HTML ); |
||
218 | |||
219 | return $link->getText( $outputMode, $this->mLinker ); |
||
220 | } |
||
221 | |||
222 | /** |
||
223 | * Returns the iCal for a single item. |
||
224 | * |
||
225 | * @param ResultArray[] $row |
||
226 | * |
||
227 | * @return [] |
||
0 ignored issues
–
show
|
|||
228 | */ |
||
229 | 3 | private function getEventParams( array $row ) { |
|
230 | 3 | $result = ''; |
|
231 | |||
232 | 3 | $subject = $row[0]->getResultSubject(); // get the object |
|
233 | 3 | $dv = DataValueFactory::getInstance()->newDataValueByItem( $subject, null ); |
|
234 | |||
235 | $params = [ |
||
236 | 3 | 'summary' => $dv->getShortWikiText() |
|
237 | ]; |
||
238 | |||
239 | 3 | $from = null; |
|
240 | 3 | $to = null; |
|
241 | 3 | foreach ( $row as /* SMWResultArray */ $field ) { |
|
242 | // later we may add more things like a generic |
||
243 | // mechanism to add whatever you want :) |
||
244 | // could include funny things like geo, description etc. though |
||
245 | 3 | $printRequest = $field->getPrintRequest(); |
|
246 | 3 | $label = strtolower( $printRequest->getLabel() ); |
|
247 | |||
248 | 3 | switch ( $label ) { |
|
249 | 3 | case 'start': |
|
250 | 3 | case 'end': |
|
251 | 2 | if ( $printRequest->getTypeID() == '_dat' ) { |
|
252 | 2 | $dataValue = $field->getNextDataValue(); |
|
253 | |||
254 | 2 | if ( $dataValue === false ) { |
|
255 | 2 | unset( $params[$label] ); |
|
256 | } else { |
||
257 | 2 | $params[$label] = $this->dateParser->parseDate( $dataValue, $label == 'end' ); |
|
258 | |||
259 | 2 | $timestamp = strtotime( $params[$label] ); |
|
260 | 2 | if ( $from === null || $timestamp < $from ) { |
|
261 | 2 | $from = $timestamp; |
|
262 | } |
||
263 | 2 | if ( $to === null || $timestamp > $to ) { |
|
264 | 2 | $to = $timestamp; |
|
265 | } |
||
266 | } |
||
267 | } |
||
268 | 2 | break; |
|
269 | 3 | case 'location': |
|
270 | 3 | case 'description': |
|
271 | 3 | case 'summary': |
|
272 | 2 | $value = $field->getNextDataValue(); |
|
273 | 2 | if ( $value !== false ) { |
|
274 | 2 | $params[$label] = $value->getShortWikiText(); |
|
275 | } |
||
276 | 2 | break; |
|
277 | } |
||
278 | } |
||
279 | |||
280 | 3 | $this->icalTimezoneFormatter->calcTransitions( $from, $to ); |
|
281 | 3 | $title = $subject->getTitle(); |
|
282 | |||
283 | 3 | $params['url'] = $title->getFullURL(); |
|
284 | 3 | $params['timestamp'] = WikiPage::factory( $title )->getTimestamp(); |
|
285 | 3 | $params['sequence'] = $title->getLatestRevID(); |
|
286 | |||
287 | 3 | return $params; |
|
288 | } |
||
289 | |||
290 | } |
||
291 |
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.