Completed
Pull Request — master (#310)
by mw
02:09
created

SRFiCalendar::getParamDefinitions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 9
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * Create iCalendar exports
4
 * @file
5
 * @ingroup SemanticResultFormats
6
 */
7
8
/**
9
 * Printer class for creating iCalendar exports
10
 * 
11
 * @author Markus Krötzsch
12
 * @author Denny Vrandecic
13
 * @author Jeroen De Dauw
14
 * 
15
 * @ingroup SemanticResultFormats
16
 */
17
class SRFiCalendar extends SMWExportPrinter {
18
	
19
	protected $m_title;
20
	protected $m_description;
21
22 2
	protected function handleParameters( array $params, $outputmode ) {
23 2
		parent::handleParameters( $params, $outputmode );
24
		
25 2
		$this->m_title = trim( $params['title'] );
26 2
		$this->m_description = trim( $params['description'] );
27 2
	}
28
29
	/**
30
	 * @see SMWIExportPrinter::getMimeType
31
	 *
32
	 * @since 1.8
33
	 *
34
	 * @param SMWQueryResult $queryResult
35
	 *
36
	 * @return string
37
	 */
38
	public function getMimeType( SMWQueryResult $queryResult ) {
39
		return 'text/calendar';
40
	}
41
42
	/**
43
	 * @see SMWIExportPrinter::getFileName
44
	 *
45
	 * @since 1.8
46
	 *
47
	 * @param SMWQueryResult $queryResult
48
	 *
49
	 * @return string|boolean
50
	 */
51
	public function getFileName( SMWQueryResult $queryResult ) {
52
		if ( $this->m_title != '' ) {
53
			return str_replace( ' ', '_', $this->m_title ) . '.ics';
54
		} else {
55
			return 'iCalendar.ics';
56
		}
57
	}
58
59 2
	public function getQueryMode( $context ) {
60 2
		return ( $context == SMWQueryProcessor::SPECIAL_PAGE ) ? SMWQuery::MODE_INSTANCES : SMWQuery::MODE_NONE;
61
	}
62
63
	public function getName() {
64
		return wfMessage( 'srf_printername_icalendar' )->text();
65
	}
66
67 2
	protected function getResultText( SMWQueryResult $res, $outputmode ) {
68 2
		return $outputmode == SMW_OUTPUT_FILE ? $this->getIcal( $res ) : $this->getIcalLink( $res, $outputmode );
69
	}
70
	
71
	/**
72
	 * Returns the query result in iCal.
73
	 * 
74
	 * @since 1.5.2
75
	 *  
76
	 * @param SMWQueryResult $res
77
	 * 
78
	 * @return string
79
	 */
80 2
	protected function getIcal( SMWQueryResult $res ) {
81 2
		$result = '';
82
		
83 2
		if ( $this->m_title == '' ) {
84 2
			global $wgSitename;
85 2
			$this->m_title = $wgSitename;
86
		}
87
		
88 2
		$result .= "BEGIN:VCALENDAR\r\n";
89 2
		$result .= "PRODID:-//SMW Project//Semantic Result Formats\r\n";
90 2
		$result .= "VERSION:2.0\r\n";
91 2
		$result .= "METHOD:PUBLISH\r\n";
92 2
		$result .= "X-WR-CALNAME:" . $this->m_title . "\r\n";
93
		
94 2
		if ( $this->m_description !== '' ) {
95 2
			$result .= "X-WR-CALDESC:" . $this->m_description . "\r\n";
96
		}
97
		
98
		// TODO: http://www.kanzaki.com/docs/ical/vtimezone.html
99
		// $result .= "BEGIN:VTIMEZONE\r\n";
100
		// $result .= "TZID:\r\n";
101
102 2
		$row = $res->getNext();
103 2
		while ( $row !== false ) {
104 2
			$result .= $this->getIcalForItem( $row );
105 2
			$row = $res->getNext();
106
		}
107
		
108
		// $result .= "END:VTIMEZONE\r\n";
109
		
110 2
		$result .= "END:VCALENDAR\r\n";
111
112 2
		return $result;
113
	}
114
115
	/**
116
	 * Returns html for a link to a query that returns the iCal.
117
	 * 
118
	 * @since 1.5.2
119
	 *  
120
	 * @param SMWQueryResult $res
121
	 * @param $outputmode
122
	 * 
123
	 * @return string
124
	 */	
125
	protected function getIcalLink( SMWQueryResult $res, $outputmode ) {
126
		if ( $this->getSearchLabel( $outputmode ) ) {
127
			$label = $this->getSearchLabel( $outputmode );
128
		} else {
129
			$label = wfMessage( 'srf_icalendar_link' )->inContentLanguage()->text();
130
		}
131
		
132
		$link = $res->getQueryLink( $label );
0 ignored issues
show
Deprecated Code introduced by
The method SMWQueryResult::getQueryLink() has been deprecated with message: since SMW 1.8

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
133
		$link->setParameter( 'icalendar', 'format' );
134
		
135
		if ( $this->m_title !== '' ) {
136
			$link->setParameter( $this->m_title, 'title' );
137
		}
138
		
139
		if ( $this->m_description !== '' ) {
140
			$link->setParameter( $this->m_description, 'description' );
141
		}
142
		
143
		if ( array_key_exists( 'limit', $this->params ) ) {
144
			$link->setParameter( $this->params['limit'], 'limit' );
145
		} else { // use a reasonable default limit
146
			$link->setParameter( 20, 'limit' );
147
		}
148
149
		// yes, our code can be viewed as HTML if requested, no more parsing needed
150
		$this->isHTML = ( $outputmode == SMW_OUTPUT_HTML ); 
151
		return $link->getText( $outputmode, $this->mLinker );
152
	}
153
	
154
	/**
155
	 * Returns the iCal for a single item.
156
	 * 
157
	 * @since 1.5.2
158
	 * 
159
	 * @param array $row
160
	 * 
161
	 * @return string
162
	 */
163 2
	protected function getIcalForItem( array $row ) {
164 2
		$result = '';
165
		
166 2
		$wikipage = $row[0]->getResultSubject(); // get the object
167 2
		$wikipage = SMWDataValueFactory::newDataItemValue( $wikipage, null );
168
169
		$params = [
170 2
			'summary' => $wikipage->getShortWikiText()
171
		];
172
		
173 2
		foreach ( $row as /* SMWResultArray */ $field ) {
174
			// later we may add more things like a generic
175
			// mechanism to add whatever you want :)
176
			// could include funny things like geo, description etc. though
177 2
			$req = $field->getPrintRequest();
178 2
			$label = strtolower( $req->getLabel() );
179
			
180
			switch ( $label ) {
181 2
				case 'start': case 'end':
182 1
					if ( $req->getTypeID() == '_dat' ) {
183 1
						$dataValue = $field->getNextDataValue();
184
185 1
						if ( $dataValue === false ) {
186 1
							unset( $params[$label] );
187
						}
188
						else {
189 1
							$params[$label] = $dataValue;
190
						}
191
					}
192 1
					break;
193 2
				case 'location': case 'description': case 'summary':
194 1
					$value = $field->getNextDataValue();
195 1
					if ( $value !== false ) {
196 1
						$params[$label] = $value->getShortWikiText();
197
					}
198 2
					break;
199
			}
200
		}
201
		
202 2
		$title = $wikipage->getTitle();
203 2
		$article = new Article( $title );
204 2
		$url = $title->getFullURL();
205
		
206 2
		$result .= "BEGIN:VEVENT\r\n";
207 2
		$result .= "SUMMARY:" . $this->escapeICalendarText( $params['summary'] ) . "\r\n";
208 2
		$result .= "URL:$url\r\n";
209 2
		$result .= "UID:$url\r\n";
210
		
211 2
		if ( array_key_exists( 'start', $params ) ) $result .= "DTSTART:" . $this->parsedate( $params['start'] ) . "\r\n";
212 2
		if ( array_key_exists( 'end', $params ) )   $result .= "DTEND:" . $this->parsedate( $params['end'], true ) . "\r\n";
213 2
		if ( array_key_exists( 'location', $params ) ) {
214 1
			$result .= "LOCATION:" . $this->escapeICalendarText( $params['location'] ) . "\r\n";
215
		}
216 2
		if ( array_key_exists( 'description', $params ) ) {
217 1
			$result .= "DESCRIPTION:" . $this->escapeICalendarText( $params['description'] ) . "\r\n";
218
		}
219
		
220 2
		$t = strtotime( str_replace( 'T', ' ', $article->getTimestamp() ) );
221 2
		$result .= "DTSTAMP:" . date( "Ymd", $t ) . "T" . date( "His", $t ) . "\r\n";
222 2
		$result .= "SEQUENCE:" . $title->getLatestRevID() . "\r\n";
223 2
		$result .= "END:VEVENT\r\n";
224
		
225 2
		return $result;
226
	}
227
228
	/**
229
	 * Extract a date string formatted for iCalendar from a SMWTimeValue object.
230
	 */
231 1
	static private function parsedate( SMWTimeValue $dv, $isend = false ) {
232 1
		$year = $dv->getYear();
233 1
		if ( ( $year > 9999 ) || ( $year < -9998 ) ) return ''; // ISO range is limited to four digits
234
		
235 1
		$year = number_format( $year, 0, '.', '' );
236 1
		$time = str_replace( ':', '', $dv->getTimeString( false ) );
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
237
		
238 1
		if ( ( $time == false ) && ( $isend ) ) { // increment by one day, compute date to cover leap years etc.
239
			$dv = SMWDataValueFactory::newTypeIDValue( '_dat', $dv->getWikiValue() . 'T00:00:00-24:00' );
240
		}
241
		
242 1
		$month = $dv->getMonth();
243 1
		if ( strlen( $month ) == 1 ) $month = '0' . $month;
244
		
245 1
		$day = $dv->getDay();
246 1
		if ( strlen( $day ) == 1 ) $day = '0' . $day;
247
		
248 1
		$result = $year . $month . $day;
249
		
250 1
		if ( $time != false ) $result .= "T$time";
251
		
252 1
		return $result;
253
	}
254
255
	/**
256
	 * Implements esaping of special characters for iCalendar properties of type TEXT. This is defined
257
	 * in RFC2445 Section 4.3.11.
258
	 */
259 2
	static private function escapeICalendarText( $text ) {
260
		// Note that \\ is a PHP escaped single \ here
261 2
		return str_replace( [ "\\", "\n", ";", "," ], [ "\\\\", "\\n", "\\;", "\\," ], $text );
262
	}
263
264
265
	/**
266
	 * @see SMWResultPrinter::getParamDefinitions
267
	 *
268
	 * @since 1.8
269
	 *
270
	 * @param $definitions array of IParamDefinition
271
	 *
272
	 * @return array of IParamDefinition|array
273
	 */
274 2
	public function getParamDefinitions( array $definitions ) {
275 2
		$params = parent::getParamDefinitions( $definitions );
276
277 2
		$params['title'] = [
278
			'default' => '',
279
			'message' => 'srf_paramdesc_icalendartitle',
280
		];
281
282 2
		$params['description'] = [
283
			'default' => '',
284
			'message' => 'srf_paramdesc_icalendardescription',
285
		];
286
287 2
		return $params;
288
	}
289
290
}
291