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