Completed
Pull Request — master (#467)
by
unknown
16:58
created

Gantt::addTask()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 1
nc 1
nop 6
1
<?php
2
/**
3
 * File holding the Gantt class
4
 *
5
 * - Add sections and tasks and
6
 *   manage the relations between them
7
 * - Sort elements based on the sortkey
8
 * - Creates config for gantt diagram
9
 *
10
 * @author Sebastian Schmid
11
 * @file
12
 * @ingroup SemanticResultFormats
13
 */
14
15
namespace SRF\Gantt;
16
17
class Gantt {
18
19
	private $mTitle;
20
	private $mAxisFormat;
21
	private $mSections = [];
22
	private $mTasks = [];
23
	private $mSortKey;
24
	private $mPriorityMapping;
25
	private $mStatusMapping;
26
27
	public function __construct( $headerParam ) {
28
		$this->setTitle( $headerParam['title'] );
29
		$this->setAxisFormat( $headerParam['axisformat'] );
30
		$this->setSortKey( $headerParam['sortkey'] );
31
		$this->setStatusMapping( $headerParam['statusmapping'] );
32
		$this->setPriorityMapping( $headerParam['prioritymapping'] );
33
	}
34
35
	private function setSortKey( $sortkey ) {
36
		$this->mSortKey = strtolower( $sortkey );
37
	}
38
39
	private function getSortKey() {
40
		return $this->mSortKey;
41
	}
42
43
	private function setPriorityMapping( $priorityMapping ) {
44
		$this->mPriorityMapping = $priorityMapping;
45
	}
46
47
	private function getPriorityMapping() {
48
		return $this->mPriorityMapping;
49
	}
50
51
	private function setStatusMapping( $statusMapping ) {
52
		$this->mStatusMapping = $statusMapping;
53
	}
54
55
	private function getStatusMapping() {
56
		return $this->mStatusMapping;
57
	}
58
59
	private function setAxisFormat( $axisFormat ) {
60
		$this->mAxisFormat = $axisFormat;
61
	}
62
63
	private function getAxisFormat() {
64
		return $this->mAxisFormat;
65
	}
66
67
	private function setTitle( $title ) {
68
		$this->mTitle = $title;
69
	}
70
71
	private function getTitle() {
72
		return $this->mTitle;
73
	}
74
75
	private function getSections() {
76
		return $this->mSections;
77
	}
78
79
	private function getTasks() {
80
		return $this->mTasks;
81
	}
82
83
	/**
84
	 * Adds a new Task to array
85
	 *
86
	 * @param string $taskID
87
	 * @param string $taskTitle
88
	 * @param array $status
89
	 * @param array $priority
90
	 * @param string $startDate
91
	 * @param string $endDate
92
	 *
93
	 */
94
95
	public function addTask( $taskID, $taskTitle, $status, $priority, $startDate, $endDate ) {
96
		$task = new GanttTask();
97
		$task->setID( $taskID );
98
		$task->setTitle( $taskTitle );
99
		$task->setTaskParam( $status, $this->getStatusMapping(), "status" );
100
		$task->setTaskParam( $priority, $this->getPriorityMapping(), "priority" );
101
		$task->setStartDate( $startDate );
102
		$task->setEndDate( $endDate );
103
104
		$this->mTasks[$taskID] = $task;
105
	}
106
107
108
	/**
109
	 * Creats a new Section with related tasks
110
	 *
111
	 * @param string $sectionID
112
	 * @param string $sectionTitle
113
	 * @param string $startDate
114
	 * @param string $endDate
115
	 * @param string $taskID
116
	 *
117
	 */
118
	public function addSection( $sectionID, $sectionTitle, $startDate, $endDate, $taskID ) {
119
120
		$sections = $this->getSections();
121
		if ( count( $sections ) != 0 ) {
122
123
			if ( array_key_exists( $sectionID, $sections ) ) {
124
125
				foreach ( $sections as $sectionObj ) {
126
					if ( $sectionObj->getID() == $sectionID ) {
127
						if ( $sectionObj->getEarliestStartDate() > $startDate ) {
128
							$sectionObj->setEarliestStartDate( $startDate );
129
						}
130
						if ( $sectionObj->getLatestEndDate() < $endDate ) {
131
							$sectionObj->setLatestEndDate( $endDate );
132
						}
133
						$sectionObj->addTask( $taskID );
134
					}
135
				}
136
			} else {
137
				$this->createNewSection( $sectionID, $sectionTitle, $startDate, $endDate, $taskID );
138
			}
139
140
		} else {
141
			// initialize GanttSection Array
142
			$this->createNewSection( $sectionID, $sectionTitle, $startDate, $endDate, $taskID );
143
		}
144
	}
145
146
	/**
147
	 * Sort Tasks based on the sortkey
148
	 *
149
	 * @param GanttTask $a
150
	 * @param GanttTask $b
151
	 *
152
	 * @return integer
153
	 */
154
	public function sortTasks( $a, $b ) {
155
156
		$sortKey = $this->getSortKey();
157
158
		// sort based on start/end date or title
159
		if ( $sortKey == 'title' ) {
160
			// sort based on title
161
			return strcmp( $a->getTitle(), $b->getTitle() );
162
		} else {
163
			if ( strpos( $sortKey, 'date' ) !== false ) {
164
				if ( strpos( $sortKey, 'start' ) !== false ) {
165
					// sort based on startDate
166
					return strcmp( $a->getStartDate(), $b->getStartDate() );
167
				} else {
168
					// sort based on endDate
169
					return strcmp( $b->getEndDate(), $a->getEndDate() );
170
				}
171
			}
172
		}
173
	}
174
175
176
	/**
177
	 * Sort Sections based on the sortkey
178
	 *
179
	 * @param GanttSection $a
180
	 * @param GanttSection $b
181
	 *
182
	 */
183
	public function sortSections( $a, $b ) {
184
185
		$sortKey = $this->getSortKey();
186
187
		// sort based on start/end date or title
188
		if ( $sortKey == 'title' ) {
189
			// sort based on title
190
			return strcmp( $a->getTitle(), $b->getTitle() );
191
		} else {
192
			if ( strpos( $sortKey, 'date' ) !== false ) {
193
				if ( strpos( $sortKey, 'start' ) !== false ) {
194
					// sort based on startDate
195
					return strcmp( $a->getEarliestStartDate(), $b->getEarliestStartDate() );
196
				} else {
197
					// sort based on endDate
198
					return strcmp( $b->getLatestEndDate(), $a->getLatestEndDate() );
199
				}
200
			}
201
		}
202
	}
203
204
	private function createNewSection( $sectionID, $sectionTitle, $startDate, $endDate, $taskID ) {
205
		$ganttSection = new GanttSection();
206
		//check if the id in the object is realy needed or is it enough to have it as array key
207
		$ganttSection->setID( $sectionID );
208
		$ganttSection->setTitle( $sectionTitle );
209
		$ganttSection->setEarliestStartDate( $startDate );
210
		$ganttSection->setLatestEndDate( $endDate );
211
		$ganttSection->addTask( $taskID );
212
213
		$this->mSections[$sectionID] = $ganttSection;
214
	}
215
216
	/**
217
	 * Creates output for mermaidjs
218
	 *
219
	 * @return string
220
	 */
221
	public function getGanttOutput() {
222
223
		$sections = $this->getSections();
224
		$tasks = $this->getTasks();
225
		$sortKey = $this->getSortKey();
226
227
		if ( !empty( $sortKey ) ) {
228
			// Order Sections
229
			usort( $sections, [ $this, "sortSections" ] );
230
			usort( $tasks, [ $this, "sortTasks" ] );
231
232
			// reorder TaskArray of current section
233
			foreach ( $sections as $section ) {
234
				$orderedTasks = [];
235
				foreach ( $tasks as $task ) {
236
237
					// check if $section->getTasks() holds ID of current task
238
					if ( in_array( $task->getID(), $section->getTasks() ) ) {
239
						$sectionTasks = $section->getTasks();
240
						//loop through tasks of current section
241
						foreach ( $sectionTasks as $taskKey => $sectionTask ) {
242
							if ( $task->getID() == $sectionTask ) {
243
								array_push( $orderedTasks, $sectionTask );
244
							}
245
						}
246
					}
247
				}
248
				$section->setTasks( $orderedTasks );
249
			}
250
		}
251
252
		/*
253
		 * Bring the "section" with no title to the first position.
254
		 * This "section" is the one that hold tasks without any section.
255
		 * If we don't display it at the beginning we have to put them into a dummy section
256
		 */
257
		foreach ( $sections as $key => $section ) {
258
			if ( $section->getTitle() == "" ) {
259
				$noSection = $section;
260
				unset( $sections[$key] );
261
			}
262
		}
263
		// push now the dummy task to the first place of the array
264
		if ( isset( $noSection ) ) {
265
			array_unshift( $sections, $noSection );
266
		}
267
268
		$title = $this->getTitle();
269
		$axisFormat = $this->getAxisFormat();
270
271
		$mermaidOut = "gantt\n";
272
		$mermaidOut .= "dateFormat YYYY-MM-DD\n";
273
		$mermaidOut .= ( !empty( $title ) ) ? "title $title\n" : "";
274
		$mermaidOut .= "axisFormat $axisFormat\n";
275
276
		// Output section and all related Issues
277
		foreach ( $sections as $section ) {
278
			if ( $section->getTitle() != "" ) {
279
				$mermaidOut .= "section " . $section->getTitle() . "\n";
280
			}
281
282
			//loop through related section tasks
283
			foreach ( $section->getTasks() as $sectionTaskValue ) {
284
				foreach ( $tasks as $taskObj ) {
285
					if ( $taskObj->getID() === $sectionTaskValue ) {
286
287
						$status = $taskObj->getStatus();
288
289
						// Get Date from timestamp
290
						$date = date_create();
291
						date_timestamp_set( $date, $taskObj->getStartDate() );
292
						$startDate = date_format( $date, 'Y-m-d' ) . ", ";
293
						date_timestamp_set( $date, $taskObj->getEndDate() );
294
						$endDate = date_format( $date, 'Y-m-d' );
295
296
						//get Priority
297
						$priority = $taskObj->getPriority();
298
299
						$mermaidOut .= $taskObj->getTitle() . "\t :" . $priority . $status . $startDate . $endDate .
300
									   "\n";
301
					}
302
				}
303
			}
304
		}
305
306
		//Hashtags mark a Comment in Mermaid, so we need to replace it with <esc>35</esc> to replace it again after rendering
307
		$mermaidOut = str_replace( "#", "<esc>35</esc>", $mermaidOut );
308
309
		return $mermaidOut;
310
	}
311
}