Completed
Pull Request — master (#467)
by
unknown
17:25
created

GanttPrinter::getResultText()   F

Complexity

Conditions 24
Paths 87

Size

Total Lines 109

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 109
rs 3.3333
c 0
b 0
f 0
cc 24
nc 87
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'] = trim( $params['theme'] );
117
118
		//Validate Theme
119
		if ( !in_array( $this->params['theme'], [ 'default', 'neutral', 'dark', 'forest' ] ) ) {
120
			$this->mErrors[] = wfMessage( 'srf-error-gantt-theme' )->text();
121
		}
122
123
		$mapping = [];
124
125
		//Validate mapping
126
		if ( !empty( trim( $params['statusmapping'] ) ) ) {
127
			$paramMapping = explode( ';', trim( $params['statusmapping'] ) );
128
129
			foreach ( $paramMapping as $pm ) {
130
				$pmKeyVal = explode( '=>', $pm, 2);
131
132
				// if no key value pair
133
				if ( count( $pmKeyVal ) !== 2 ) {
134
					$this->mErrors[] = wfMessage( 'srf-error-gantt-mapping-assignment', 'statusmapping' )->text();
135
				} else {
136
					$mapping[trim( $pmKeyVal[0] )] = trim( $pmKeyVal[1] );
137
138
					// check if the common status keys are used
139
					if ( trim( $pmKeyVal[1] ) !== 'active' && trim( $pmKeyVal[1] ) !== 'done' ) {
140
						$this->mErrors[] = wfMessage( 'srf-error-gantt-mapping-keywords' )->text();
141
					}
142
				}
143
			}
144
		}
145
		if ( !empty( trim( $params['prioritymapping'] ) ) ) {
146
			$paramMapping = explode( ';', trim( $params['prioritymapping'] ) );
147
148
			foreach ( $paramMapping as $pm ) {
149
				$pmKeyVal = explode( '=>', $pm, 2 );
150
151
				// if no key value pair
152
				if ( count( $pmKeyVal ) !== 2 ) {
153
					$this->mErrors[] = wfMessage( 'srf-error-gantt-mapping-assignment', 'prioritymapping' )->text();
154
				} else {
155
					$mapping[trim( $pmKeyVal[0] )] = trim( $pmKeyVal[1] );
156
157
					// check if the common status keys are used
158
					if ( trim( $pmKeyVal[1] ) !== 'crit' ) {
159
						$this->mErrors[] = wfMessage( 'srf-error-gantt-mapping-keywords' )->text();
160
					}
161
				}
162
			}
163
		}
164
165
		$this->mGantt = $this->getGantt();
166
167
	}
168
169
	/**
170
	 * Return serialised results in specified format.
171
	 * @param SMWQueryResult $queryResult
172
	 * @param $outputmode
173
	 * @return string
174
	 */
175
	protected function getResultText( SMWQueryResult $queryResult, $outputmode ) {
176
177
		// Show warning if Extension:Mermaid is not available
178
		if ( !class_exists( 'Mermaid' ) && !class_exists( 'Mermaid\\MermaidParserFunction' ) ) {
179
			$queryResult->addErrors( [wfMessage('')->text()] );
180
			return '';
181
		}
182
183
		// Load general Modules
184
		SMWOutputs::requireResource( 'ext.srf.gantt' );
185
186
		//Add Tasks & Sections
187
		while ( $row = $queryResult->getNext() ) {
188
189
			$status = [];
190
			$priority = [];
191
			$startDate = '';
192
			$endDate = '';
193
			$taskID = '';
194
			$taskTitle = '';
195
			$sections = [];
196
197
			// Loop through all field of a row
198
			foreach ( $row as $field ) {
199
200
				$fieldLabel = $field->getPrintRequest()->getLabel();
201
202
				//get values
203
				foreach ( $field->getContent() as $dataItem ) {
204
205
					switch ( $fieldLabel ) {
206
						case 'section':
207
							$sections[$dataItem->getTitle()->getPrefixedDBKey()] = $dataItem->getSortKey();
208
							break;
209
						case 'task':
210
							if ( $dataItem instanceof SMWDIBlob ) {
211
								$taskTitle = $dataItem->getString();
212
								$taskID = $field->getResultSubject()->getTitle()->getPrefixedDBKey();
213
							}
214
							break;
215
						case 'startdate':
216
							if ( $dataItem instanceof SMWDITime ) {
217
								$startDate = $dataItem->getMwTimestamp();
218
							}
219
							break;
220
						case 'enddate':
221
							if ( $dataItem instanceof SMWDITime ) {
222
								$endDate = $dataItem->getMwTimestamp();
223
							}
224
							break;
225
						case 'status':
226
							if ( $dataItem instanceof SMWDIBlob ) {
227
								$status[] = $dataItem->getString();
228
							}
229
							break;
230
						case 'priority':
231
							if ( $dataItem instanceof SMWDIBlob ) {
232
								$priority[] = $dataItem->getString();
233
							}
234
							break;
235
					}
236
				}
237
			}
238
239
			// Add section/Task
240
			// Title, TaskID, StartDate and EndDate are required
241
			if ( $taskID !== '' && $taskTitle !== '' && $startDate !== '' && $endDate !== '' ) {
242
				$this->mGantt->addTask( $taskID, $taskTitle, $status, $priority, $startDate, $endDate );
243
244
				// If no section was found, put task into a dummy section object
245
				// "gantt-no-section#21780240" is used to identify Tasks that with no section (dummy section)
246
				if ( count( $sections ) == 0 ) {
247
					$this->mGantt->addSection( 'gantt-no-section#21780240', '', $startDate, $endDate, $taskID );
248
				} else {
249
					foreach ( $sections as $sectionID => $sectionTitle ) {
250
						$this->mGantt->addSection( $sectionID, $sectionTitle, $startDate, $endDate, $taskID );
251
					}
252
				}
253
			}
254
		}
255
256
		// Improve unique id by adding a random number
257
		$id = uniqid( 'srf-gantt-' . rand( 1, 10000 ) );
258
259
		// Add gantt configurations
260
		$config = [
261
			'theme' => $this->params['theme'],
262
			'gantt' => [
263
				'leftPadding'    => intval( $this->params['leftpadding'] ),
264
				'titleTopMargin' => intval( $this->params['titletopmargin'] ),
265
				'barHeight'      => intval( $this->params['barheight'] ),
266
				'barGap'         => intval( $this->params['bargap'] )
267
			]
268
		];
269
270
		// Manage Output
271
		if ( !empty( $this->mErrors ) ) {
272
			return $queryResult->addErrors( $this->mErrors );
273
		} else {
274
			return Html::rawElement( 'div', [
275
				'id'           => $id,
276
				'class'        => 'srf-gantt',
277
				'data-mermaid' => json_encode( [
278
					'content' => $this->mGantt->getGanttOutput(),
279
					'config'  => $config
280
				])
281
			], Html::rawElement( 'div', [ 'class' => 'mermaid-dots' ]));
282
		}
283
	}
284
285
	private function getGantt(){
286
		return new Gantt( $this->params );
287
	}
288
}