iCalendarFileExportPrinter   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 280
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 81%

Importance

Changes 0
Metric Value
wmc 33
lcom 1
cbo 5
dl 0
loc 280
ccs 81
cts 100
cp 0.81
rs 9.76
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A getName() 0 3 1
A getFileName() 0 8 2
A getQueryMode() 0 3 2
A getParamDefinitions() 0 20 1
A handleParameters() 0 6 1
A getResultText() 0 8 2
A getIcal() 0 32 3
A getIcalLink() 0 30 5
A getEventParams() 0 31 2
C filterField() 0 44 13
A getMimeType() 0 3 1
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 3
	public function getMimeType( QueryResult $queryResult ) {
68 3
		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
Documentation introduced by mwjames
The doc-type [] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

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.

Loading history...
228
	 */
229 3
	private function getEventParams( array $row ) {
230
231 3
		$result = '';
0 ignored issues
show
Unused Code introduced by Jeroen De Dauw
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
232
233 3
		$subject = $row[0]->getResultSubject(); // get the object
234 3
		$dataValue = DataValueFactory::getInstance()->newDataValueByItem( $subject, null );
235
236
		$params = [
237 3
			'summary' => $dataValue->getShortWikiText()
238
		];
239
240 3
		$params['from'] = null;
241 3
		$params['to'] = null;
242
243 3
		foreach ( $row as /* SMWResultArray */ $field ) {
244 3
			$this->filterField( $field, $params );
245
		}
246
247 3
		$this->icalTimezoneFormatter->calcTransitions(
248 3
			$params['from'],
249 3
			$params['to']
250
		);
251
252 3
		$title = $subject->getTitle();
253
254 3
		$params['url'] = $title->getFullURL();
255 3
		$params['timestamp'] = WikiPage::factory( $title )->getTimestamp();
256 3
		$params['sequence'] = $title->getLatestRevID();
257
258 3
		return $params;
259
	}
260
261 3
	private function filterField( $field, &$params ) {
262
263
		// later we may add more things like a generic
264
		// mechanism to add whatever you want :)
265
		// could include funny things like geo, description etc. though
266 3
		$printRequest = $field->getPrintRequest();
267 3
		$label = strtolower( $printRequest->getLabel() );
268
269 3
		switch ( $label ) {
270 3
			case 'start':
271 3
			case 'end':
272 2
				if ( $printRequest->getTypeID() == '_dat' ) {
273 2
					$dataValue = $field->getNextDataValue();
274
275 2
					if ( $dataValue === false ) {
276 2
						unset( $params[$label] );
277
					} else {
278 2
						$params[$label] = $this->dateParser->parseDate(
279 2
							$dataValue,
280 2
							$label == 'end'
281
						);
282
283 2
						$timestamp = strtotime( $params[$label] );
284
285 2
						if ( $params['from'] === null || $timestamp < $params['from'] ) {
286 2
							$params['from'] = $timestamp;
287
						}
288
289 2
						if ( $params['to'] === null || $timestamp > $params['to'] ) {
290 2
							$params['to'] = $timestamp;
291
						}
292
					}
293
				}
294 2
				break;
295 3
			case 'location':
296 3
			case 'description':
297 3
			case 'summary':
298 2
				$value = $field->getNextDataValue();
299 2
				if ( $value !== false ) {
300 2
					$params[$label] = $value->getShortWikiText();
301
				}
302 2
				break;
303
		}
304 3
	}
305
306
}
307