Completed
Pull Request — master (#467)
by
unknown
33:07 queued 13:08
created

GanttPrinter::handleParameters()   B

Complexity

Conditions 10
Paths 4

Size

Total Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 53
rs 7.1587
c 0
b 0
f 0
cc 10
nc 4
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * SMW result printer for Gantt Diagrams using mermaidjs.
4
 * https://github.com/knsv/mermaid
5
 *
6
 * In order to use this printer you need to have
7
 * the Mermaid MediaWiki extension installed.
8
 * https://www.mediawiki.org/wiki/Extension:Mermaid
9
 *
10
 * @file Gantt.php
11
 * @ingroup SemanticResultFormats
12
 *
13
 * @licence GNU GPL v2+
14
 * @author Sebastian Schmid
15
 */
16
17
namespace SRF\Gantt;
18
19
use SMWOutputs;
20
use SMWQueryResult;
21
use SMWResultPrinter;
22
use SMWDITime;
23
use SMWDIBlob;
24
use Html;
25
26
class GanttPrinter extends SMWResultPrinter {
27
28
	protected $mGantt = null;
29
	protected $mErrors = [];
30
31
	public function getName() {
32
		return wfMessage( 'srf-printername-gantt' )->text();
33
	}
34
35
	public function getParamDefinitions( array $definitions ) {
36
		$params = parent::getParamDefinitions( $definitions );
37
38
		$params[] = [
39
			'type'    => 'string',
40
			'name'    => 'diagramtitle',
41
			'message' => 'srf-paramdesc-gantt-diagramtitle',
42
			'default' => ''
43
		];
44
45
		$params[] = [
46
			'type'    => 'string',
47
			'name'    => 'theme',
48
			'message' => 'srf-paramdesc-gantt-diagramtheme',
49
			'default' => 'default'
50
		];
51
52
		$params[] = [
53
			'type'    => 'string',
54
			'name'    => 'axisformat',
55
			'message' => 'srf-paramdesc-gantt-axisformat',
56
			'default' => '%m/%d/%Y'
57
		];
58
59
		$params[] = [
60
			'type'    => 'string',
61
			'name'    => 'statusmapping',
62
			'message' => 'srf-paramdesc-gantt-statusmapping',
63
			'default' => ''
64
		];
65
66
		$params[] = [
67
			'type'    => 'string',
68
			'name'    => 'prioritymapping',
69
			'message' => 'srf-paramdesc-gantt-prioritymapping',
70
			'default' => ''
71
		];
72
73
		$params[] = [
74
			'type'    => 'integer',
75
			'name'    => 'titletopmargin',
76
			'message' => 'srf-paramdesc-gantt-titletopmargin',
77
			'default' => 25
78
		];
79
80
		$params[] = [
81
			'type'    => 'integer',
82
			'name'    => 'barheight',
83
			'message' => 'srf-paramdesc-gantt-barheight',
84
			'default' => 20
85
		];
86
87
		$params[] = [
88
			'type'    => 'integer',
89
			'name'    => 'leftpadding',
90
			'message' => 'srf-paramdesc-gantt-leftpadding',
91
			'default' => 75
92
		];
93
94
		$params[] = [
95
			'type'    => 'integer',
96
			'name'    => 'bargap',
97
			'message' => 'srf-paramdesc-gantt-bargap',
98
			'default' => 4
99
		];
100
101
		return $params;
102
	}
103
104
	/**
105
	 * Handle (set) the result format parameters
106
	 *
107
	 * @see SMWResultPrinter::handleParameters()
108
	 */
109
	protected function handleParameters( array $params, $outputmode ) {
110
111
		//Set header params
112
		$this->params['title'] = trim( $params['diagramtitle'] );
113
		$this->params['axisformat'] = trim( $params['axisformat'] );
114
		$this->params['statusmapping'] = trim( $params['statusmapping'] );
115
		$this->params['prioritymapping'] = trim( $params['prioritymapping'] );
116
		$this->params['theme'] = $this->getValidatedTheme($params['theme']);
117
		$mapping = [];
118
119
		//Validate mapping
120
		if ( !empty( trim( $params['statusmapping'] ) ) ) {
121
			$paramMapping = explode( ';', trim( $params['statusmapping'] ) );
122
123
			foreach ( $paramMapping as $pm ) {
124
				$pmKeyVal = explode( '=>', $pm, 2);
125
126
				// if no key value pair
127
				if ( count( $pmKeyVal ) !== 2 ) {
128
					$this->mErrors[] = wfMessage( 'srf-error-gantt-mapping-assignment', 'statusmapping' )->text();
129
				} else {
130
					$mapping[trim( $pmKeyVal[0] )] = trim( $pmKeyVal[1] );
131
132
					// check if the common status keys are used
133
					if ( trim( $pmKeyVal[1] ) !== 'active' && trim( $pmKeyVal[1] ) !== 'done' ) {
134
						$this->mErrors[] = wfMessage( 'srf-error-gantt-mapping-keywords' )->text();
135
					}
136
				}
137
			}
138
		}
139
		if ( !empty( trim( $params['prioritymapping'] ) ) ) {
140
			$paramMapping = explode( ';', trim( $params['prioritymapping'] ) );
141
142
			foreach ( $paramMapping as $pm ) {
143
				$pmKeyVal = explode( '=>', $pm, 2 );
144
145
				// if no key value pair
146
				if ( count( $pmKeyVal ) !== 2 ) {
147
					$this->mErrors[] = wfMessage( 'srf-error-gantt-mapping-assignment', 'prioritymapping' )->text();
148
				} else {
149
					$mapping[trim( $pmKeyVal[0] )] = trim( $pmKeyVal[1] );
150
151
					// check if the common status keys are used
152
					if ( trim( $pmKeyVal[1] ) !== 'crit' ) {
153
						$this->mErrors[] = wfMessage( 'srf-error-gantt-mapping-keywords' )->text();
154
					}
155
				}
156
			}
157
		}
158
159
		$this->mGantt = $this->getGantt();
160
161
	}
162
163
	/**
164
	 * Return serialised results in specified format.
165
	 * @param SMWQueryResult $queryResult
166
	 * @param $outputmode
167
	 * @return string
168
	 */
169
	protected function getResultText( SMWQueryResult $queryResult, $outputmode ) {
170
171
		// Show warning if Extension:Mermaid is not available
172
		if ( !class_exists( 'Mermaid' ) && !class_exists( 'Mermaid\\MermaidParserFunction' ) ) {
173
			$queryResult->addErrors( [wfMessage('')->text()] );
174
			return '';
175
		}
176
177
		// Load general Modules
178
		SMWOutputs::requireResource( 'ext.srf.gantt' );
179
180
		//Add Tasks & Sections
181
		while ( $row = $queryResult->getNext() ) {
182
183
			$status = [];
184
			$priority = [];
185
			$startDate = '';
186
			$endDate = '';
187
			$taskID = '';
188
			$taskTitle = '';
189
			$sections = [];
190
191
			// Loop through all field of a row
192
			foreach ( $row as $field ) {
193
194
				$fieldLabel = $field->getPrintRequest()->getLabel();
195
196
				//get values
197
				foreach ( $field->getContent() as $dataItem ) {
198
199
					switch ( $fieldLabel ) {
200
						case 'section':
201
							$sections[$dataItem->getTitle()->getPrefixedDBKey()] = $dataItem->getSortKey();
202
							break;
203
						case 'task':
204
							if ( $dataItem instanceof SMWDIBlob ) {
205
								$taskTitle = $dataItem->getString();
206
								$taskID = $field->getResultSubject()->getTitle()->getPrefixedDBKey();
207
							}
208
							break;
209
						case 'startdate':
210
							if ( $dataItem instanceof SMWDITime ) {
211
								$startDate = $dataItem->getMwTimestamp();
212
							}
213
							break;
214
						case 'enddate':
215
							if ( $dataItem instanceof SMWDITime ) {
216
								$endDate = $dataItem->getMwTimestamp();
217
							}
218
							break;
219
						case 'status':
220
							if ( $dataItem instanceof SMWDIBlob ) {
221
								$status[] = $dataItem->getString();
222
							}
223
							break;
224
						case 'priority':
225
							if ( $dataItem instanceof SMWDIBlob ) {
226
								$priority[] = $dataItem->getString();
227
							}
228
							break;
229
					}
230
				}
231
			}
232
233
			// Add section/Task
234
			// Title, TaskID, StartDate and EndDate are required
235
			if ( $taskID !== '' && $taskTitle !== '' && $startDate !== '' && $endDate !== '' ) {
236
				$this->mGantt->addTask( $taskID, $taskTitle, $status, $priority, $startDate, $endDate );
237
238
				// If no section was found, put task into a dummy section object
239
				// "gantt-no-section#21780240" is used to identify Tasks that with no section (dummy section)
240
				if ( count( $sections ) == 0 ) {
241
					$this->mGantt->addSection( 'gantt-no-section#21780240', '', $startDate, $endDate, $taskID );
242
				} else {
243
					foreach ( $sections as $sectionID => $sectionTitle ) {
244
						$this->mGantt->addSection( $sectionID, $sectionTitle, $startDate, $endDate, $taskID );
245
					}
246
				}
247
			}
248
		}
249
250
		// Improve unique id by adding a random number
251
		$id = uniqid( 'srf-gantt-' . rand( 1, 10000 ) );
252
253
		// Add gantt configurations
254
		$config = [
255
			'theme' => $this->params['theme'],
256
			'gantt' => [
257
				'leftPadding'    => intval( $this->params['leftpadding'] ),
258
				'titleTopMargin' => intval( $this->params['titletopmargin'] ),
259
				'barHeight'      => intval( $this->params['barheight'] ),
260
				'barGap'         => intval( $this->params['bargap'] )
261
			]
262
		];
263
264
		// Manage Output
265
		if ( !empty( $this->mErrors ) ) {
266
			return $queryResult->addErrors( $this->mErrors );
267
		} else {
268
			return Html::rawElement( 'div', [
269
				'id'           => $id,
270
				'class'        => 'srf-gantt',
271
				'data-mermaid' => json_encode( [
272
					'content' => $this->mGantt->getGanttOutput(),
273
					'config'  => $config
274
				])
275
			], Html::rawElement( 'div', [ 'class' => 'mermaid-dots' ]));
276
		}
277
	}
278
279
	private function getGantt(){
280
		return new Gantt( $this->params );
281
	}
282
283
	/**
284
	 * Return valid theme as string
285
	 * @param String $theme
286
	 *
287
	 * @return string
288
	 */
289
	private function getValidatedTheme( $theme ) {
290
		$theme = trim( $theme );
291
292
		if ( !in_array( $this->params['theme'], [ 'default', 'neutral', 'dark', 'forest' ] ) ) {
293
			$this->mErrors[] = wfMessage( 'srf-error-gantt-theme' )->text();
294
		}
295
296
		return $theme;
297
	}
298
}