ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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{
17 protected $lng;
18
22 protected $db;
23
24 protected $question; // [SurveyQuestion]
25 protected $finished_ids; // [array]
26 protected $chart_width = 400;
27 protected $chart_height = 300;
28
36 public function __construct(SurveyQuestion $a_question, array $a_finished_ids = null)
37 {
38 global $DIC;
39
40 $this->lng = $DIC->language();
41 $this->db = $DIC->database();
42 $this->question = $a_question;
43 $this->finished_ids = $a_finished_ids;
44 }
45
46
47 //
48 // RESULTS
49 //
50
56 public function getResults()
57 {
58 $results = new ilSurveyEvaluationResults($this->question);
59 $answers = $this->getAnswerData();
60
61 $this->parseResults(
63 (array) $answers[0],
64 method_exists($this->question, "getCategories")
65 ? $this->question->getCategories()
66 : null
67 );
68
69 return $results;
70 }
71
79 protected function parseResults(ilSurveyEvaluationResults $a_results, array $a_answers, SurveyCategories $a_categories = null)
80 {
81 $num_users_answered = sizeof($a_answers);
82
83 $a_results->setUsersAnswered($num_users_answered);
84 $a_results->setUsersSkipped($this->getNrOfParticipants() - $num_users_answered);
85
86 // parse answers
87 $has_multi = false;
88 $selections = array();
89 foreach ($a_answers as $active_id => $answers) {
90 // :TODO:
91 if (sizeof($answers) > 1) {
92 $has_multi = true;
93 }
94 foreach ($answers as $answer) {
95 // map selection value to scale/category
96 if ($a_categories &&
97 $answer["value"] != "") {
98 $scale = $a_categories->getCategoryForScale($answer["value"] + 1);
99 if ($scale instanceof ilSurveyCategory) {
100 $answer["value"] = $scale->scale;
101 }
102 }
103
105 $active_id,
106 $answer["value"],
107 $answer["text"]
108 );
109 $a_results->addAnswer($parsed);
110
111 if ($answer["value"] != "") {
112 $selections[$answer["value"]]++;
113 }
114 }
115 }
116
117 $total = array_sum($selections);
118
119 if ($total) {
120 // mode
121 $mode_nr = max($selections);
122 $tmp_mode = $selections;
123 asort($tmp_mode, SORT_NUMERIC);
124 $mode = array_keys($tmp_mode, $mode_nr);
125 $a_results->setMode($mode, $mode_nr);
126
127 if (!$has_multi) {
128 // median
129 ksort($selections, SORT_NUMERIC);
130 $median = array();
131 foreach ($selections as $value => $count) {
132 for ($i = 0; $i < $count; $i++) {
133 $median[] = $value;
134 }
135 }
136 if ($total % 2 == 0) {
137 $lower = $median[($total / 2) - 1];
138 $upper = $median[($total / 2)];
139 $median_value = 0.5 * ($lower + $upper);
140 if ($a_categories &&
141 round($median_value) != $median_value) {
142 // mapping calculated value to scale values
143 $median_value = array($lower, $upper);
144 }
145 } else {
146 $median_value = $median[(($total + 1) / 2) - 1];
147 }
148 $a_results->setMedian($median_value);
149 }
150 }
151
152 if ($a_categories) {
153 // selections by category
154 for ($c = 0; $c < $a_categories->getCategoryCount(); $c++) {
155 $cat = $a_categories->getCategory($c);
156 $scale = $cat->scale;
157
159 $cat,
160 $selections[$scale],
161 $total
162 ? $selections[$scale] / $total
163 : null
164 );
165 $a_results->addVariable($var);
166 }
167 }
168 }
169
170 public function parseUserSpecificResults($a_qres, $a_user_id)
171 {
172 $parsed_results = array();
173
174 if (is_array($a_qres)) {
175 foreach ($a_qres as $row_idx => $row_results) {
176 $row_title = $row_results[0];
177 $user_results = $row_results[1]->getUserResults($a_user_id);
178 if ($user_results) {
179 foreach ($user_results as $item) {
180 // :TODO: layout
181 $tmp = $row_title . ": ";
182 if ($item[0] !== "") {
183 $tmp .= $item[0];
184 }
185 if ($item[1] && $item[0]) {
186 $tmp .= ", \"" . nl2br($item[1]) . "\"";
187 } elseif ($item[1]) {
188 $tmp .= "\"" . nl2br($item[1]) . "\"";
189 }
190 $parsed_results[$row_idx . "-" . $item[2]] = $tmp;
191 }
192 }
193 }
194 } else {
195 $user_results = $a_qres->getUserResults($a_user_id);
196 if ($user_results) {
197 foreach ($user_results as $item) {
198 // :TODO: layout
199 if ($item[0] !== "") {
200 $tmp = $item[0];
201 }
202 if ($item[1] && $item[0]) {
203 $tmp .= ", \"" . nl2br($item[1]) . "\"";
204 } elseif ($item[1]) {
205 $tmp = "\"" . nl2br($item[1]) . "\"";
206 }
207 $parsed_results[$item[2]] = $tmp;
208 }
209 }
210 }
211
212 return $parsed_results;
213 }
214
215
216 //
217 // DETAILS
218 //
219
228 public function getGrid($a_results, $a_abs = true, $a_perc = true)
229 {
231
232 if ((bool) $a_abs && (bool) $a_perc) {
233 $cols = array(
234 $lng->txt("category_nr_selected"),
235 $lng->txt("svy_fraction_of_selections")
236 );
237 } elseif ((bool) $a_abs) {
238 $cols = array(
239 $lng->txt("category_nr_selected")
240 );
241 } else {
242 $cols = array(
243 $lng->txt("svy_fraction_of_selections")
244 );
245 }
246
247 $res = array(
248 "cols" => $cols,
249 "rows" => array()
250 );
251
252 $vars = $a_results->getVariables();
253 if ($vars) {
254 foreach ($vars as $var) {
255 $perc = $var->perc
256 ? sprintf("%.2f", $var->perc * 100) . "%"
257 : "0%";
258
259 if ((bool) $a_abs && (bool) $a_perc) {
260 $res["rows"][] = array(
261 $var->cat->title,
262 $var->abs,
263 $perc
264 );
265 } elseif ((bool) $a_abs) {
266 $res["rows"][] = array(
267 $var->cat->title,
268 $var->abs
269 );
270 } else {
271 $res["rows"][] = array(
272 $var->cat->title,
273 $perc
274 );
275 }
276 }
277 }
278
279 return $res;
280 }
281
288 public function getTextAnswers($a_results)
289 {
290 return $a_results->getMappedTextAnswers();
291 }
292
293 protected function getChartColors()
294 {
295 return array(
296 // flot "default" theme
297 "#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed",
298 // http://godsnotwheregodsnot.blogspot.de/2012/09/color-distribution-methodology.html
299 "#1CE6FF", "#FF34FF", "#FF4A46", "#008941", "#006FA6", "#A30059",
300 "#FFDBE5", "#7A4900", "#0000A6", "#63FFAC", "#B79762", "#004D43", "#8FB0FF", "#997D87",
301 "#5A0007", "#809693", "#FEFFE6", "#1B4400", "#4FC601", "#3B5DFF", "#4A3B53", "#FF2F80",
302 "#61615A", "#BA0900", "#6B7900", "#00C2A0", "#FFAA92", "#FF90C9", "#B903AA", "#D16100",
303 "#DDEFFF", "#000035", "#7B4F4B", "#A1C299", "#300018", "#0AA6D8", "#013349", "#00846F",
304 "#372101", "#FFB500", "#C2FFED", "#A079BF", "#CC0744", "#C0B9B2", "#C2FF99", "#001E09",
305 "#00489C", "#6F0062", "#0CBD66", "#EEC3FF", "#456D75", "#B77B68", "#7A87A1", "#788D66",
306 "#885578", "#FAD09F", "#FF8A9A", "#D157A0", "#BEC459", "#456648", "#0086ED", "#886F4C",
307 "#34362D", "#B4A8BD", "#00A6AA", "#452C2C", "#636375", "#A3C8C9", "#FF913F", "#938A81",
308 "#575329", "#00FECF", "#B05B6F", "#8CD0FF", "#3B9700", "#04F757", "#C8A1A1", "#1E6E00",
309 "#7900D7", "#A77500", "#6367A9", "#A05837", "#6B002C", "#772600", "#D790FF", "#9B9700",
310 "#549E79", "#FFF69F", "#201625", "#72418F", "#BC23FF", "#99ADC0", "#3A2465", "#922329",
311 "#5B4534", "#FDE8DC", "#404E55", "#0089A3", "#CB7E98", "#A4E804", "#324E72", "#6A3A4C"
312 );
313 }
314
321 public function getChart($a_results)
322 {
323 include_once "Services/Chart/classes/class.ilChart.php";
324 $chart = ilChart::getInstanceByType(ilChart::TYPE_GRID, $a_results->getQuestion()->getId());
325 $chart->setYAxisToInteger(true);
326
327 $colors = $this->getChartColors();
328 $chart->setColors($colors);
329
330 // :TODO:
331 $chart->setsize($this->chart_width, $this->chart_height);
332
333 $vars = $a_results->getVariables();
334
335 $legend = $labels = array();
336 foreach ($vars as $idx => $var) {
337 $data = $chart->getDataInstance(ilChartGrid::DATA_BARS);
338 $data->setBarOptions(0.5, "center");
339 $data->setFill(1);
340 $chart->addData($data);
341
342 // labels
343 $labels[$idx] = "";
344 $legend[] = array(
345 $var->cat->title,
346 $colors[$idx]
347 );
348 $data->setLabel($var->cat->title);
349
350 $data->addPoint($idx, $var->abs);
351 }
352
353 $chart->setTicks($labels, false, true);
354
355 return array(
356 $chart->getHTML(),
357 $legend
358 );
359 }
360
361
362 //
363 // USER-SPECIFIC
364 //
365
371 public function getSkippedValue()
372 {
373 include_once "Modules/Survey/classes/class.ilObjSurvey.php";
375 }
376
377
378 //
379 // HELPER
380 //
381
382 protected function getSurveyId()
383 {
385
386 // #18968
387 $set = $ilDB->query("SELECT survey_fi" .
388 " FROM svy_svy_qst" .
389 " WHERE question_fi = " . $ilDB->quote($this->question->getId(), "integer"));
390 $row = $ilDB->fetchAssoc($set);
391 return $row["survey_fi"];
392 }
393
394
400 protected function getNrOfParticipants()
401 {
403
404 if (is_array($this->finished_ids)) {
405 return sizeof($this->finished_ids);
406 }
407
408 $set = $ilDB->query("SELECT finished_id FROM svy_finished" .
409 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer"));
410 return $set->numRows();
411 }
412
413 protected function getAnswerData()
414 {
416
417 $res = array();
418
419 $sql = "SELECT svy_answer.* FROM svy_answer" .
420 " JOIN svy_finished ON (svy_finished.finished_id = svy_answer.active_fi)" .
421 " WHERE svy_answer.question_fi = " . $ilDB->quote($this->question->getId(), "integer") .
422 " AND svy_finished.survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer");
423 if (is_array($this->finished_ids)) {
424 $sql .= " AND " . $ilDB->in("svy_finished.finished_id", $this->finished_ids, "", "integer");
425 }
426 $set = $ilDB->query($sql);
427 while ($row = $ilDB->fetchAssoc($set)) {
428 $res[(int) $row["rowvalue"]][(int) $row["active_fi"]][] = array(
429 "value" => $row["value"],
430 "text" => $row["textanswer"]
431 );
432 }
433
434 return $res;
435 }
436
437
438 //
439 // EXPORT
440 //
441
442 public function exportResults($a_results, $a_do_title, $a_do_label)
443 {
444 $question = $a_results->getQuestion();
445
446 $res = array();
447
448 if ($a_do_title) {
449 $res[] = $question->getTitle();
450 }
451 if ($a_do_label) {
452 $res[] = $question->label;
453 }
454
455 $res[] = $question->getQuestiontext();
457
458 $res[] = (int) $a_results->getUsersAnswered();
459 $res[] = (int) $a_results->getUsersSkipped();
460
461 // :TODO:
462 $res[] = is_array($a_results->getModeValue())
463 ? implode(", ", $a_results->getModeValue())
464 : $a_results->getModeValue();
465
466 $res[] = $a_results->getModeValueAsText();
467 $res[] = (int) $a_results->getModeNrOfSelections();
468
469 // :TODO:
470 $res[] = $a_results->getMedianAsText();
471
472 $res[] = $a_results->getMean();
473
474 return array($res);
475 }
476
483 public function getExportGrid($a_results)
484 {
486
487 $res = array(
488 "cols" => array(
489 $lng->txt("title"),
490 $lng->txt("value"),
491 $lng->txt("category_nr_selected"),
492 $lng->txt("svy_fraction_of_selections")
493 ),
494 "rows" => array()
495 );
496
497 $vars = $a_results->getVariables();
498 if ($vars) {
499 foreach ($vars as $var) {
500 $res["rows"][] = array(
501 $var->cat->title,
502 $var->cat->scale,
503 $var->abs,
504 $var->perc
505 ? sprintf("%.2f", $var->perc * 100) . "%"
506 : "0%"
507 );
508 }
509 }
510
511 return $res;
512 }
513
522 public function getUserSpecificVariableTitles(array &$a_title_row, array &$a_title_row2, $a_do_title, $a_do_label)
523 {
524 // type-specific
525 }
526
534 abstract public function addUserSpecificResults(array &$a_row, $a_user_id, $a_results);
535}
$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)
$i
Definition: disco.tpl.php:19
$legend
$row
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
global $ilDB
$results
Definition: svg-scanner.php:47
$data
Definition: bench.php:6
$cols
Definition: xhr_table.php:11