ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.SurveyQuestionEvaluation.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4include_once "Modules/Survey/classes/class.ilSurveyEvaluationResults.php";
5
13{
14 protected $question; // [SurveyQuestion]
15 protected $finished_ids; // [array]
16 protected $chart_width = 400;
17 protected $chart_height = 300;
18
26 public function __construct(SurveyQuestion $a_question, array $a_finished_ids = null)
27 {
28 $this->question = $a_question;
29 $this->finished_ids = $a_finished_ids;
30 }
31
32
33 //
34 // RESULTS
35 //
36
42 public function getResults()
43 {
44 $results = new ilSurveyEvaluationResults($this->question);
45 $answers = $this->getAnswerData();
46
47 $this->parseResults(
48 $results,
49 (array)$answers[0],
50 method_exists($this->question, "getCategories")
51 ? $this->question->getCategories()
52 : null
53 );
54
55 return $results;
56 }
57
65 protected function parseResults(ilSurveyEvaluationResults $a_results, array $a_answers, SurveyCategories $a_categories = null)
66 {
67 $num_users_answered = sizeof($a_answers);
68
69 $a_results->setUsersAnswered($num_users_answered);
70 $a_results->setUsersSkipped($this->getNrOfParticipants()-$num_users_answered);
71
72 // parse answers
73 $has_multi = false;
74 $selections = array();
75 foreach($a_answers as $active_id => $answers)
76 {
77 // :TODO:
78 if(sizeof($answers) > 1)
79 {
80 $has_multi = true;
81 }
82 foreach($answers as $answer)
83 {
84 // map selection value to scale/category
85 if($a_categories &&
86 $answer["value"] != "")
87 {
88 $scale = $a_categories->getCategoryForScale($answer["value"]+1);
89 if($scale instanceof ilSurveyCategory)
90 {
91 $answer["value"] = $scale->scale;
92 }
93 }
94
96 $active_id,
97 $answer["value"],
98 $answer["text"]
99 );
100 $a_results->addAnswer($parsed);
101
102 if($answer["value"] != "")
103 {
104 $selections[$answer["value"]]++;
105 }
106 }
107 }
108
109 $total = array_sum($selections);
110
111 if($total)
112 {
113 // mode
114 $mode_nr = max($selections);
115 $tmp_mode = $selections;
116 asort($tmp_mode, SORT_NUMERIC);
117 $mode = array_keys($tmp_mode, $mode_nr);
118 $a_results->setMode($mode, $mode_nr);
119
120 if(!$has_multi)
121 {
122 // median
123 ksort($selections, SORT_NUMERIC);
124 $median = array();
125 foreach($selections as $value => $count)
126 {
127 for($i = 0; $i < $count; $i++)
128 {
129 $median[] = $value;
130 }
131 }
132 if($total % 2 == 0)
133 {
134 $lower = $median[($total/2)-1];
135 $upper = $median[($total/2)];
136 $median_value = 0.5 * ($lower + $upper);
137 if($a_categories &&
138 round($median_value) != $median_value)
139 {
140 // mapping calculated value to scale values
141 $median_value = array($lower, $upper);
142 }
143 }
144 else
145 {
146 $median_value = $median[(($total+1)/2)-1];
147 }
148 $a_results->setMedian($median_value);
149 }
150 }
151
152 if($a_categories)
153 {
154 // selections by category
155 for ($c = 0; $c < $a_categories->getCategoryCount(); $c++)
156 {
157 $cat = $a_categories->getCategory($c);
158 $scale = $cat->scale;
159
161 $cat,
162 $selections[$scale],
163 $total
164 ? $selections[$scale]/$total
165 : null
166 );
167 $a_results->addVariable($var);
168 }
169 }
170 }
171
172 public function parseUserSpecificResults($a_qres, $a_user_id)
173 {
174 $parsed_results = array();
175
176 if(is_array($a_qres))
177 {
178 foreach($a_qres as $row_idx => $row_results)
179 {
180 $row_title = $row_results[0];
181 $user_results = $row_results[1]->getUserResults($a_user_id);
182 if($user_results)
183 {
184 foreach($user_results as $item)
185 {
186 // :TODO: layout
187 $tmp = $row_title.": ";
188 if($item[0] !== "")
189 {
190 $tmp .= $item[0];
191 }
192 if($item[1] && $item[0])
193 {
194 $tmp .= ", \"".nl2br($item[1])."\"";
195 }
196 else if($item[1])
197 {
198 $tmp .= "\"".nl2br($item[1])."\"";
199 }
200 $parsed_results[$row_idx."-".$item[2]] = $tmp;
201 }
202 }
203 }
204
205 }
206 else
207 {
208 $user_results = $a_qres->getUserResults($a_user_id);
209 if($user_results)
210 {
211 foreach($user_results as $item)
212 {
213 // :TODO: layout
214 if($item[0] !== "")
215 {
216 $tmp = $item[0];
217 }
218 if($item[1] && $item[0])
219 {
220 $tmp .= ", \"".nl2br($item[1])."\"";
221 }
222 else if($item[1])
223 {
224 $tmp = "\"".nl2br($item[1])."\"";
225 }
226 $parsed_results[$item[2]] = $tmp;
227 }
228 }
229 }
230
231 return $parsed_results;
232 }
233
234
235 //
236 // DETAILS
237 //
238
247 public function getGrid($a_results, $a_abs = true, $a_perc = true)
248 {
249 global $lng;
250
251 if((bool)$a_abs && (bool)$a_perc)
252 {
253 $cols = array(
254 $lng->txt("category_nr_selected"),
255 $lng->txt("svy_fraction_of_selections")
256 );
257 }
258 else if((bool)$a_abs)
259 {
260 $cols = array(
261 $lng->txt("category_nr_selected")
262 );
263 }
264 else
265 {
266 $cols = array(
267 $lng->txt("svy_fraction_of_selections")
268 );
269 }
270
271 $res = array(
272 "cols" => $cols,
273 "rows" => array()
274 );
275
276 $vars = $a_results->getVariables();
277 if($vars)
278 {
279 foreach($vars as $var)
280 {
281 $perc = $var->perc
282 ? sprintf("%.2f", $var->perc*100)."%"
283 : "0%";
284
285 if((bool)$a_abs && (bool)$a_perc)
286 {
287 $res["rows"][] = array(
288 $var->cat->title,
289 $var->abs,
290 $perc
291 );
292 }
293 else if((bool)$a_abs)
294 {
295 $res["rows"][] = array(
296 $var->cat->title,
297 $var->abs
298 );
299 }
300 else
301 {
302 $res["rows"][] = array(
303 $var->cat->title,
304 $perc
305 );
306 }
307 }
308 }
309
310 return $res;
311 }
312
319 public function getTextAnswers($a_results)
320 {
321 return $a_results->getMappedTextAnswers();
322 }
323
324 protected function getChartColors()
325 {
326 return array(
327 // flot "default" theme
328 "#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed",
329 // http://godsnotwheregodsnot.blogspot.de/2012/09/color-distribution-methodology.html
330 "#1CE6FF", "#FF34FF", "#FF4A46", "#008941", "#006FA6", "#A30059",
331 "#FFDBE5", "#7A4900", "#0000A6", "#63FFAC", "#B79762", "#004D43", "#8FB0FF", "#997D87",
332 "#5A0007", "#809693", "#FEFFE6", "#1B4400", "#4FC601", "#3B5DFF", "#4A3B53", "#FF2F80",
333 "#61615A", "#BA0900", "#6B7900", "#00C2A0", "#FFAA92", "#FF90C9", "#B903AA", "#D16100",
334 "#DDEFFF", "#000035", "#7B4F4B", "#A1C299", "#300018", "#0AA6D8", "#013349", "#00846F",
335 "#372101", "#FFB500", "#C2FFED", "#A079BF", "#CC0744", "#C0B9B2", "#C2FF99", "#001E09",
336 "#00489C", "#6F0062", "#0CBD66", "#EEC3FF", "#456D75", "#B77B68", "#7A87A1", "#788D66",
337 "#885578", "#FAD09F", "#FF8A9A", "#D157A0", "#BEC459", "#456648", "#0086ED", "#886F4C",
338 "#34362D", "#B4A8BD", "#00A6AA", "#452C2C", "#636375", "#A3C8C9", "#FF913F", "#938A81",
339 "#575329", "#00FECF", "#B05B6F", "#8CD0FF", "#3B9700", "#04F757", "#C8A1A1", "#1E6E00",
340 "#7900D7", "#A77500", "#6367A9", "#A05837", "#6B002C", "#772600", "#D790FF", "#9B9700",
341 "#549E79", "#FFF69F", "#201625", "#72418F", "#BC23FF", "#99ADC0", "#3A2465", "#922329",
342 "#5B4534", "#FDE8DC", "#404E55", "#0089A3", "#CB7E98", "#A4E804", "#324E72", "#6A3A4C"
343 );
344 }
345
352 public function getChart($a_results)
353 {
354 include_once "Services/Chart/classes/class.ilChart.php";
355 $chart = ilChart::getInstanceByType(ilChart::TYPE_GRID, $a_results->getQuestion()->getId());
356 $chart->setYAxisToInteger(true);
357
358 $colors = $this->getChartColors();
359 $chart->setColors($colors);
360
361 // :TODO:
362 $chart->setsize($this->chart_width, $this->chart_height);
363
364 $vars = $a_results->getVariables();
365
366 $legend = $labels = array();
367 foreach($vars as $idx => $var)
368 {
369 $data = $chart->getDataInstance(ilChartGrid::DATA_BARS);
370 $data->setBarOptions(0.5, "center");
371 $data->setFill(1);
372 $chart->addData($data);
373
374 // labels
375 $labels[$idx] = "";
376 $legend[] = array(
377 $var->cat->title,
378 $colors[$idx]
379 );
380 $data->setLabel($var->cat->title);
381
382 $data->addPoint($idx, $var->abs);
383 }
384
385 $chart->setTicks($labels, false, true);
386
387 return array(
388 $chart->getHTML(),
389 $legend
390 );
391 }
392
393
394 //
395 // USER-SPECIFIC
396 //
397
403 public function getSkippedValue()
404 {
405 include_once "Modules/Survey/classes/class.ilObjSurvey.php";
407 }
408
409
410 //
411 // HELPER
412 //
413
414 protected function getSurveyId()
415 {
416 global $ilDB;
417
418 // #18968
419 $set = $ilDB->query("SELECT survey_fi".
420 " FROM svy_svy_qst".
421 " WHERE question_fi = ".$ilDB->quote($this->question->getId(), "integer"));
422 $row = $ilDB->fetchAssoc($set);
423 return $row["survey_fi"];
424 }
425
426
432 protected function getNrOfParticipants()
433 {
434 global $ilDB;
435
436 if(is_array($this->finished_ids))
437 {
438 return sizeof($this->finished_ids);
439 }
440
441 $set = $ilDB->query("SELECT finished_id FROM svy_finished".
442 " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer"));
443 return $set->numRows();
444 }
445
446 protected function getAnswerData()
447 {
448 global $ilDB;
449
450 $res = array();
451
452 $sql = "SELECT svy_answer.* FROM svy_answer".
453 " JOIN svy_finished ON (svy_finished.finished_id = svy_answer.active_fi)".
454 " WHERE svy_answer.question_fi = ".$ilDB->quote($this->question->getId(), "integer").
455 " AND svy_finished.survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer");
456 if(is_array($this->finished_ids))
457 {
458 $sql .= " AND ".$ilDB->in("svy_finished.finished_id", $this->finished_ids, "", "integer");
459 }
460 $set = $ilDB->query($sql);
461 while($row = $ilDB->fetchAssoc($set))
462 {
463 $res[(int)$row["rowvalue"]][(int)$row["active_fi"]][] = array(
464 "value" => $row["value"],
465 "text" => $row["textanswer"]
466 );
467 }
468
469 return $res;
470 }
471
472
473 //
474 // EXPORT
475 //
476
477 public function exportResults($a_results, $a_do_title, $a_do_label)
478 {
479 $question = $a_results->getQuestion();
480
481 $res = array();
482
483 if($a_do_title)
484 {
485 $res[] = $question->getTitle();
486 }
487 if($a_do_label)
488 {
489 $res[] = $question->label;
490 }
491
492 $res[] = $question->getQuestiontext();
494
495 $res[] = (int)$a_results->getUsersAnswered();
496 $res[] = (int)$a_results->getUsersSkipped();
497
498 // :TODO:
499 $res[] = is_array($a_results->getModeValue())
500 ? implode(", ", $a_results->getModeValue())
501 : $a_results->getModeValue();
502
503 $res[] = $a_results->getModeValueAsText();
504 $res[] = (int)$a_results->getModeNrOfSelections();
505
506 // :TODO:
507 $res[] = $a_results->getMedianAsText();
508
509 $res[] = $a_results->getMean();
510
511 return array($res);
512 }
513
520 public function getExportGrid($a_results)
521 {
522 global $lng;
523
524 $res = array(
525 "cols" => array(
526 $lng->txt("title"),
527 $lng->txt("value"),
528 $lng->txt("category_nr_selected"),
529 $lng->txt("svy_fraction_of_selections")
530 ),
531 "rows" => array()
532 );
533
534 $vars = $a_results->getVariables();
535 if($vars)
536 {
537 foreach($vars as $var)
538 {
539 $res["rows"][] = array(
540 $var->cat->title,
541 $var->cat->scale,
542 $var->abs,
543 $var->perc
544 ? sprintf("%.2f", $var->perc*100)."%"
545 : "0%"
546 );
547 }
548 }
549
550 return $res;
551 }
552
561 public function getUserSpecificVariableTitles(array &$a_title_row, array &$a_title_row2, $a_do_title, $a_do_label)
562 {
563 // type-specific
564 }
565
573 abstract public function addUserSpecificResults(array &$a_row, $a_user_id, $a_results);
574}
sprintf('%.4f', $callTime)
$total
Definition: Utf8Test.php:87
An exception for terminatinating execution or to throw for unit testing.
Class SurveyCategories.
__construct(SurveyQuestion $a_question, array $a_finished_ids=null)
Constructor.
getSkippedValue()
Get caption for skipped value.
parseResults(ilSurveyEvaluationResults $a_results, array $a_answers, SurveyCategories $a_categories=null)
Parse answer data into results instance.
getExportGrid($a_results)
Get grid data.
addUserSpecificResults(array &$a_row, $a_user_id, $a_results)
exportResults($a_results, $a_do_title, $a_do_label)
getUserSpecificVariableTitles(array &$a_title_row, array &$a_title_row2, $a_do_title, $a_do_label)
Get title columns for user-specific export.
getGrid($a_results, $a_abs=true, $a_perc=true)
Get grid data.
getTextAnswers($a_results)
Get text answers.
getNrOfParticipants()
Returns the number of participants for a survey.
Basic class for all survey question types.
static _getQuestionTypeName($type_tag)
Return the translation for a given question type tag.
static getInstanceByType($a_type, $a_id)
Get type instance.
const TYPE_GRID
static getSurveySkippedValue()
Survey category class.
setMode($a_value, $a_nr_of_selections)
addVariable(ilSurveyEvaluationResultsVariable $a_variable)
addAnswer(ilSurveyEvaluationResultsAnswer $a_answer)
global $lng
Definition: privfeed.php:17
$results
global $ilDB