ILIAS  eassessment Revision 61809
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.SurveyMatrixQuestion.php
Go to the documentation of this file.
1 <?php
2  /*
3  +----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +----------------------------------------------------------------------------+
22 */
23 
24 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
25 include_once "./Modules/Survey/classes/inc.SurveyConstants.php";
26 
37 {
43  var $columns;
44 
50  var $rows;
51 
58 
65 
73 
81 
89 
90  /*
91  * Layout of the matrix question
92  *
93  * @var array
94  */
95  var $layout;
96 
97  /*
98  * Use placeholders for the column titles
99  *
100  * @var boolean
101  */
103 
104  /*
105  * Show a legend
106  *
107  * @var boolean
108  */
109  var $legend;
110 
112 
114 
116 
117  /*
118  * Use random order for rows
119  *
120  * @var boolean
121  */
123 
125 
127 
129 
131 
132 
147  var $subtype;
148 
160  $title = "",
161  $description = "",
162  $author = "",
163  $questiontext = "",
164  $owner = -1
165  )
166  {
168  $this->subtype = 0;
169  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyCategories.php";
170  $this->columns = new SurveyCategories();
171  $this->rows = new SurveyCategories();
172  $this->bipolar_adjective1 = "";
173  $this->bipolar_adjective2 = "";
174  $this->rowSeparators = 0;
175  $this->columnSeparators = 0;
176  $this->neutralColumnSeparator = 1;
177  }
178 
186  function getColumnCount()
187  {
188  return $this->columns->getCategoryCount();
189  }
190 
198  function removeColumn($index)
199  {
200  $this->columns->removeCategory($index);
201  }
202 
210  function removeColumns($array)
211  {
212  $this->columns->removeCategories($array);
213  }
214 
223  {
224  $this->columns->removeCategoryWithName($name);
225  }
226 
230  public function getColumns()
231  {
232  return $this->columns;
233  }
234 
243  function getColumn($index)
244  {
245  return $this->columns->getCategory($index);
246  }
247 
248  function getColumnForScale($scale)
249  {
250  return $this->columns->getCategoryForScale($scale);
251  }
252 
261  {
262  return $this->columns->getCategoryIndex($name);
263  }
264 
265 
272  function flushColumns()
273  {
274  $this->columns->flushCategories();
275  }
276 
283  function getRowCount()
284  {
285  return $this->rows->getCategoryCount();
286  }
287 
293  function addRow($a_text, $a_other, $a_label)
294  {
295  $this->rows->addCategory($a_text, $a_other, 0, $a_label);
296  }
297 
304  function addRowAtPosition($a_text, $a_other, $a_position)
305  {
306  $this->rows->addCategoryAtPosition($a_text, $a_position, $a_other);
307  }
308 
315  function flushRows()
316  {
317  $this->rows = new SurveyCategories();
318  }
319 
326  function getRow($a_index)
327  {
328  return $this->rows->getCategory($a_index);
329  }
330 
331  function moveRowUp($index)
332  {
333  $this->rows->moveCategoryUp($index);
334  }
335 
336  function moveRowDown($index)
337  {
338  $this->rows->moveCategoryDown($index);
339  }
340 
348  function removeRows($array)
349  {
350  $this->rows->removeCategories($array);
351  }
352 
358  public function removeRow($index)
359  {
360  $this->rows->removeCategory($index);
361  }
362 
370  function getBipolarAdjective($a_index)
371  {
372  switch ($a_index)
373  {
374  case 1:
375  return (strlen($this->bipolar_adjective2)) ? $this->bipolar_adjective2 : NULL;
376  break;
377  case 0:
378  default:
379  return (strlen($this->bipolar_adjective1)) ? $this->bipolar_adjective1 : NULL;
380  break;
381  }
382  return NULL;
383  }
384 
392  function setBipolarAdjective($a_index, $a_value)
393  {
394  switch ($a_index)
395  {
396  case 1:
397  $this->bipolar_adjective2 = $a_value;
398  break;
399  case 0:
400  default:
401  $this->bipolar_adjective1 = $a_value;
402  break;
403  }
404  }
405 
412  function addPhrase($phrase_id)
413  {
414  global $ilUser;
415  global $ilDB;
416 
417  $result = $ilDB->queryF("SELECT svy_category.* FROM svy_category, svy_phrase_cat WHERE svy_phrase_cat.category_fi = svy_category.category_id AND svy_phrase_cat.phrase_fi = %s AND (svy_category.owner_fi = %s OR svy_category.owner_fi = %s) ORDER BY svy_phrase_cat.sequence",
418  array('integer', 'integer', 'integer'),
419  array($phrase_id, 0, $ilUser->getId())
420  );
421  while ($row = $ilDB->fetchAssoc($result))
422  {
423  if (($row["defaultvalue"] == 1) && ($row["owner_fi"] == 0))
424  {
425  $this->columns->addCategory($this->lng->txt($row["title"]));
426  }
427  else
428  {
429  $this->columns->addCategory($row["title"]);
430  }
431  }
432  }
433 
442  {
443  global $ilDB;
444 
445  $result = $ilDB->queryF("SELECT svy_question.*, " . $this->getAdditionalTableName() . ".* FROM svy_question, " . $this->getAdditionalTableName() . " WHERE svy_question.question_id = %s AND svy_question.question_id = " . $this->getAdditionalTableName() . ".question_fi",
446  array('integer'),
447  array($id)
448  );
449  if ($result->numRows() == 1)
450  {
451  return $ilDB->fetchAssoc($result);
452  }
453  else
454  {
455  return array();
456  }
457  }
458 
465  function loadFromDb($id)
466  {
467  global $ilDB;
468  $result = $ilDB->queryF("SELECT svy_question.*, " . $this->getAdditionalTableName() . ".* FROM svy_question LEFT JOIN " . $this->getAdditionalTableName() . " ON " . $this->getAdditionalTableName() . ".question_fi = svy_question.question_id WHERE svy_question.question_id = %s",
469  array('integer'),
470  array($id)
471  );
472  if ($result->numRows() == 1)
473  {
474  $data = $ilDB->fetchAssoc($result);
475  $this->setId($data["question_id"]);
476  $this->setTitle($data["title"]);
477  $this->label = $data['label'];
478  $this->setDescription($data["description"]);
479  $this->setObjId($data["obj_fi"]);
480  $this->setAuthor($data["author"]);
481  $this->setOwner($data["owner_fi"]);
482  include_once("./Services/RTE/classes/class.ilRTE.php");
483  $this->setQuestiontext(ilRTE::_replaceMediaObjectImageSrc($data["questiontext"], 1));
484  $this->setObligatory($data["obligatory"]);
485  $this->setComplete($data["complete"]);
486  $this->setOriginalId($data["original_id"]);
487  $this->setSubtype($data["subtype"]);
488  $this->setRowSeparators($data["row_separators"]);
489  $this->setNeutralColumnSeparator($data["neutral_column_separator"]);
490  $this->setColumnSeparators($data["column_separators"]);
491  $this->setColumnPlaceholders($data["column_placeholders"]);
492  $this->setLegend($data["legend"]);
493  $this->setSingleLineRowCaption($data["singleline_row_caption"]);
494  $this->setRepeatColumnHeader($data["repeat_column_header"]);
495  $this->setColumnHeaderPosition($data["column_header_position"]);
496  $this->setRandomRows($data["random_rows"]);
497  $this->setColumnOrder($data["column_order"]);
498  $this->setColumnImages($data["column_images"]);
499  $this->setRowImages($data["row_images"]);
500  $this->setBipolarAdjective(0, $data["bipolar_adjective1"]);
501  $this->setBipolarAdjective(1, $data["bipolar_adjective2"]);
502  $this->setLayout($data["layout"]);
503  $this->flushColumns();
504 
505  $result = $ilDB->queryF("SELECT svy_variable.*, svy_category.title, svy_category.neutral FROM svy_variable, svy_category WHERE svy_variable.question_fi = %s AND svy_variable.category_fi = svy_category.category_id ORDER BY sequence ASC",
506  array('integer'),
507  array($id)
508  );
509  if ($result->numRows() > 0)
510  {
511  while ($data = $ilDB->fetchAssoc($result))
512  {
513  $this->columns->addCategory($data["title"], $data["other"], $data["neutral"], null, ($data['scale']) ? $data['scale'] : ($data['sequence'] + 1));
514  }
515  }
516 
517  $result = $ilDB->queryF("SELECT * FROM svy_qst_matrixrows WHERE question_fi = %s ORDER BY sequence",
518  array('integer'),
519  array($id)
520  );
521  while ($row = $ilDB->fetchAssoc($result))
522  {
523  $this->addRow($row["title"], $row['other'], $row['label']);
524  }
525  }
527  }
528 
535  function isComplete()
536  {
537  if (
538  strlen($this->getTitle()) &&
539  strlen($this->getAuthor()) &&
540  strlen($this->getQuestiontext()) &&
541  $this->getColumnCount() &&
542  $this->getRowCount()
543  )
544  {
545  return 1;
546  }
547  else
548  {
549  return 0;
550  }
551  }
552 
558  function saveToDb($original_id = NULL, $withanswers = true)
559  {
560  global $ilDB;
561 
562  $affectedRows = parent::saveToDb($original_id);
563 
564  if ($affectedRows == 1)
565  {
566  $affectedRows = $ilDB->manipulateF("DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
567  array('integer'),
568  array($this->getId())
569  );
570  $affectedRows = $ilDB->manipulateF("INSERT INTO " . $this->getAdditionalTableName() . " (
571  question_fi, subtype, column_separators, row_separators, neutral_column_separator,column_placeholders,
572  legend, singleline_row_caption, repeat_column_header, column_header_position, random_rows,
573  column_order, column_images, row_images, bipolar_adjective1, bipolar_adjective2, layout, tstamp)
574  VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
575  array(
576  'integer', 'integer', 'text', 'text', 'text', 'integer', 'text', 'text', 'text',
577  'text', 'text', 'text', 'text', 'text', 'text', 'text', 'text', 'integer'
578  ),
579  array(
580  $this->getId(),
581  $this->getSubtype(),
582  $this->getColumnSeparators(),
583  $this->getRowSeparators(),
584  $this->getNeutralColumnSeparator(),
585  $this->getColumnPlaceholders(),
586  $this->getLegend(),
587  $this->getSingleLineRowCaption(),
588  $this->getRepeatColumnHeader(),
589  $this->getColumnHeaderPosition(),
590  $this->getRandomRows(),
591  $this->getColumnOrder(),
592  $this->getColumnImages(),
593  $this->getRowImages(),
594  $this->getBipolarAdjective(0),
595  $this->getBipolarAdjective(1),
596  serialize($this->getLayout()),
597  time()
598  )
599  );
600 
601  // saving material uris in the database
602  $this->saveMaterial();
603 
604  $this->saveColumnsToDb();
605  $this->saveRowsToDb();
606  }
607  }
608 
609  function saveBipolarAdjectives($adjective1, $adjective2)
610  {
611  global $ilDB;
612 
613  $affectedRows = $ilDB->manipulateF("UPDATE " . $this->getAdditionalTableName() . " SET bipolar_adjective1 = %s, bipolar_adjective2 = %s WHERE question_fi = %s",
614  array('text', 'text', 'integer'),
615  array((strlen($adjective1)) ? $adjective1 : NULL, (strlen($adjective2)) ? $adjective2 : NULL, $this->getId())
616  );
617  }
618 
627  function saveColumnToDb($columntext, $neutral = 0)
628  {
629  global $ilUser, $ilDB;
630 
631  $result = $ilDB->queryF("SELECT title, category_id FROM svy_category WHERE title = %s AND neutral = %s AND owner_fi = %s",
632  array('text', 'text', 'integer'),
633  array($columntext, $neutral, $ilUser->getId())
634  );
635  $insert = FALSE;
636  $returnvalue = "";
637  if ($result->numRows())
638  {
639  $insert = TRUE;
640  while ($row = $ilDB->fetchAssoc($result))
641  {
642  if (strcmp($row["title"], $columntext) == 0)
643  {
644  $returnvalue = $row["category_id"];
645  $insert = FALSE;
646  }
647  }
648  }
649  else
650  {
651  $insert = TRUE;
652  }
653  if ($insert)
654  {
655  $next_id = $ilDB->nextId('svy_category');
656  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_category (category_id, title, defaultvalue, owner_fi, neutral, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
657  array('integer', 'text', 'text', 'integer', 'text', 'integer'),
658  array($next_id, $columntext, 0, $ilUser->getId(), $neutral, time())
659  );
660  $returnvalue = $next_id;
661  }
662  return $returnvalue;
663  }
664 
665  function saveColumnsToDb($original_id = "")
666  {
667  global $ilDB;
668 
669  // save columns
670  $question_id = $this->getId();
671  if (strlen($original_id))
672  {
673  $question_id = $original_id;
674  }
675 
676  // delete existing column relations
677  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_variable WHERE question_fi = %s",
678  array('integer'),
679  array($question_id)
680  );
681  // create new column relations
682  for ($i = 0; $i < $this->getColumnCount(); $i++)
683  {
684  $cat = $this->getColumn($i);
685  $column_id = $this->saveColumnToDb($cat->title, $cat->neutral);
686  $next_id = $ilDB->nextId('svy_variable');
687  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_variable (variable_id, category_fi, question_fi, value1, other, sequence, scale, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)",
688  array('integer','integer','integer','float','integer','integer', 'integer','integer'),
689  array($next_id, $column_id, $question_id, ($i + 1), $cat->other, $i, ($cat->scale > 0) ? $cat->scale : null, time())
690  );
691  }
692  $this->saveCompletionStatus($original_id);
693  }
694 
695  function saveRowsToDb($original_id = "")
696  {
697  global $ilDB;
698 
699  // save rows
700  $question_id = $this->getId();
701  if (strlen($original_id))
702  {
703  $question_id = $original_id;
704  }
705 
706  // delete existing rows
707  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qst_matrixrows WHERE question_fi = %s",
708  array('integer'),
709  array($question_id)
710  );
711  // create new rows
712  for ($i = 0; $i < $this->getRowCount(); $i++)
713  {
714  $row = $this->getRow($i);
715  $next_id = $ilDB->nextId('svy_qst_matrixrows');
716  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qst_matrixrows (id_svy_qst_matrixrows, title, label, other, sequence, question_fi) VALUES (%s, %s, %s, %s, %s, %s)",
717  array('integer','text','text','integer','integer','integer'),
718  array($next_id, $row->title, $row->label, ($row->other) ? 1 : 0, $i, $question_id)
719  );
720  }
721  $this->saveCompletionStatus($original_id);
722  }
723 
730  function toXML($a_include_header = TRUE, $obligatory_state = "")
731  {
732  include_once("./Services/Xml/classes/class.ilXmlWriter.php");
733  $a_xml_writer = new ilXmlWriter;
734  $a_xml_writer->xmlHeader();
735  $this->insertXML($a_xml_writer, $a_include_header, $obligatory_state);
736  $xml = $a_xml_writer->xmlDumpMem(FALSE);
737  if (!$a_include_header)
738  {
739  $pos = strpos($xml, "?>");
740  $xml = substr($xml, $pos + 2);
741  }
742  return $xml;
743  }
744 
753  function insertXML(&$a_xml_writer, $a_include_header = TRUE, $obligatory_state = "")
754  {
755  $attrs = array(
756  "id" => $this->getId(),
757  "title" => $this->getTitle(),
758  "type" => $this->getQuestiontype(),
759  "subtype" => $this->getSubtype(),
760  "obligatory" => $this->getObligatory()
761  );
762  $a_xml_writer->xmlStartTag("question", $attrs);
763 
764  $a_xml_writer->xmlElement("description", NULL, $this->getDescription());
765  $a_xml_writer->xmlElement("author", NULL, $this->getAuthor());
766  $a_xml_writer->xmlStartTag("questiontext");
767  $this->addMaterialTag($a_xml_writer, $this->getQuestiontext());
768  $a_xml_writer->xmlEndTag("questiontext");
769 
770  $a_xml_writer->xmlStartTag("matrix");
771  $a_xml_writer->xmlStartTag("matrixrows");
772  for ($i = 0; $i < $this->getRowCount(); $i++)
773  {
774  $attrs = array(
775  "id" => $i
776  );
777  if (strlen($this->getRow($i)->label))
778  {
779  $attrs['label'] = $this->getRow($i)->label;
780  }
781  if ($this->getRow($i)->other)
782  {
783  $attrs['other'] = 1;
784  }
785  $a_xml_writer->xmlStartTag("matrixrow", $attrs);
786  $this->addMaterialTag($a_xml_writer, $this->getRow($i)->title);
787  $a_xml_writer->xmlEndTag("matrixrow");
788  }
789  $a_xml_writer->xmlEndTag("matrixrows");
790 
791  $a_xml_writer->xmlStartTag("responses");
792  if (strlen($this->getBipolarAdjective(0)) && (strlen($this->getBipolarAdjective(1))))
793  {
794  $a_xml_writer->xmlStartTag("bipolar_adjectives");
795  $attribs = array(
796  "label" => "0"
797  );
798  $a_xml_writer->xmlElement("adjective", $attribs, $this->getBipolarAdjective(0));
799  $attribs = array(
800  "label" => "1"
801  );
802  $a_xml_writer->xmlElement("adjective", $attribs, $this->getBipolarAdjective(1));
803  $a_xml_writer->xmlEndTag("bipolar_adjectives");
804  }
805  for ($i = 0; $i < $this->getColumnCount(); $i++)
806  {
807  $attrs = array(
808  "id" => $i
809  );
810  if ($this->getColumn($i)->neutral)
811  {
812  $attrs['label'] = 'neutral';
813  }
814  switch ($this->getSubtype())
815  {
816  case 0:
817  $a_xml_writer->xmlStartTag("response_single", $attrs);
818  break;
819  case 1:
820  $a_xml_writer->xmlStartTag("response_multiple", $attrs);
821  break;
822  }
823  $this->addMaterialTag($a_xml_writer, $this->getColumn($i)->title);
824  switch ($this->getSubtype())
825  {
826  case 0:
827  $a_xml_writer->xmlEndTag("response_single");
828  break;
829  case 1:
830  $a_xml_writer->xmlEndTag("response_multiple");
831  break;
832  }
833  }
834 
835  $a_xml_writer->xmlEndTag("responses");
836  $a_xml_writer->xmlEndTag("matrix");
837 
838  if (count($this->material))
839  {
840  if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $this->material["internal_link"], $matches))
841  {
842  $attrs = array(
843  "label" => $this->material["title"]
844  );
845  $a_xml_writer->xmlStartTag("material", $attrs);
846  $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
847  if (strcmp($matches[1], "") != 0)
848  {
849  $intlink = $this->material["internal_link"];
850  }
851  $a_xml_writer->xmlElement("mattext", NULL, $intlink);
852  $a_xml_writer->xmlEndTag("material");
853  }
854  }
855 
856  $a_xml_writer->xmlStartTag("metadata");
857  $a_xml_writer->xmlStartTag("metadatafield");
858  $a_xml_writer->xmlElement("fieldlabel", NULL, "column_separators");
859  $a_xml_writer->xmlElement("fieldentry", NULL, $this->getColumnSeparators());
860  $a_xml_writer->xmlEndTag("metadatafield");
861 
862  $a_xml_writer->xmlStartTag("metadatafield");
863  $a_xml_writer->xmlElement("fieldlabel", NULL, "row_separators");
864  $a_xml_writer->xmlElement("fieldentry", NULL, $this->getRowSeparators());
865  $a_xml_writer->xmlEndTag("metadatafield");
866 
867  $a_xml_writer->xmlStartTag("metadatafield");
868  $a_xml_writer->xmlElement("fieldlabel", NULL, "neutral_column_separator");
869  $a_xml_writer->xmlElement("fieldentry", NULL, $this->getNeutralColumnSeparator());
870  $a_xml_writer->xmlEndTag("metadatafield");
871 
872  $a_xml_writer->xmlStartTag("metadatafield");
873  $a_xml_writer->xmlElement("fieldlabel", NULL, "layout");
874  $a_xml_writer->xmlElement("fieldentry", NULL, serialize($this->getLayout()));
875  $a_xml_writer->xmlEndTag("metadatafield");
876 
877  $a_xml_writer->xmlEndTag("metadata");
878 
879  $a_xml_writer->xmlEndTag("question");
880  }
881 
882  function syncWithOriginal()
883  {
884  if ($this->getOriginalId())
885  {
887  $this->saveColumnsToDb($this->getOriginalId());
888  $this->saveRowsToDb($this->getOriginalId());
889  }
890  }
891 
892 
900  function addStandardNumbers($lower_limit, $upper_limit)
901  {
902  for ($i = $lower_limit; $i <= $upper_limit; $i++)
903  {
904  $this->columns->addCategory($i);
905  }
906  }
907 
915  function savePhrase($title)
916  {
917  global $ilUser;
918  global $ilDB;
919 
920  $next_id = $ilDB->nextId('svy_phrase');
921  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_phrase (phrase_id, title, defaultvalue, owner_fi, tstamp) VALUES (%s, %s, %s, %s, %s)",
922  array('integer','text','text','integer','integer'),
923  array($next_id, $title, 1, $ilUser->getId(), time())
924  );
925  $phrase_id = $next_id;
926 
927  $counter = 1;
928  foreach ($_SESSION['save_phrase_data'] as $data)
929  {
930  $next_id = $ilDB->nextId('svy_category');
931  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_category (category_id, title, defaultvalue, owner_fi, tstamp) VALUES (%s, %s, %s, %s, %s)",
932  array('integer','text','text','integer','integer'),
933  array($next_id, $data['answer'], 1, $ilUser->getId(), time())
934  );
935  $category_id = $next_id;
936  $next_id = $ilDB->nextId('svy_phrase_cat');
937  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_phrase_cat (phrase_category_id, phrase_fi, category_fi, sequence, other, scale) VALUES (%s, %s, %s, %s, %s, %s)",
938  array('integer', 'integer', 'integer','integer', 'integer', 'integer'),
939  array($next_id, $phrase_id, $category_id, $counter, ($data['other']) ? 1 : 0, $data['scale'])
940  );
941  $counter++;
942  }
943  }
944 
951  function getQuestionType()
952  {
953  return "SurveyMatrixQuestion";
954  }
955 
963  {
964  return "svy_qst_matrix";
965  }
966 
973  function &getWorkingDataFromUserInput($post_data)
974  {
975  $data = array();
976  foreach ($post_data as $key => $value)
977  {
978  switch ($this->getSubtype())
979  {
980  case 0:
981  if (preg_match("/matrix_" . $this->getId() . "_(\d+)/", $key, $matches))
982  {
983  if (is_array($value))
984  {
985  foreach ($value as $val)
986  {
987  array_push($data, array("value" => $val, "rowvalue" => $matches[1], "textanswer" => $post_data['matrix_other_' . $this->getId() . '_' . $matches[1]]));
988  }
989  }
990  else
991  {
992  array_push($data, array("value" => $value, "rowvalue" => $matches[1], "textanswer" => $post_data['matrix_other_' . $this->getId() . '_' . $matches[1]]));
993  }
994  }
995  break;
996  case 1:
997  if (preg_match("/matrix_" . $this->getId() . "_(\d+)/", $key, $matches))
998  {
999  if (is_array($value))
1000  {
1001  foreach ($value as $val)
1002  {
1003  array_push($data, array("value" => $val, "rowvalue" => $matches[1], "textanswer" => $post_data['matrix_other_' . $this->getId() . '_' . $matches[1]]));
1004  }
1005  }
1006  else
1007  {
1008  array_push($data, array("value" => $value, "rowvalue" => $matches[1], "textanswer" => $post_data['matrix_other_' . $this->getId() . '_' . $matches[1]]));
1009  }
1010  }
1011  break;
1012  }
1013  }
1014  return $data;
1015  }
1016 
1026  function checkUserInput($post_data, $survey_id)
1027  {
1028  if (!$this->getObligatory($survey_id)) return "";
1029  switch ($this->getSubtype())
1030  {
1031  case 0:
1032  $counter = 0;
1033  foreach ($post_data as $key => $value)
1034  {
1035  if (preg_match("/matrix_" . $this->getId() . "_(\d+)/", $key, $matches))
1036  {
1037  if (array_key_exists('matrix_other_' . $this->getId() . "_" . $matches[1], $post_data) && strlen($post_data['matrix_other_' . $this->getId() . "_" . $matches[1]]) == 0)
1038  {
1039  return $this->lng->txt("question_mr_no_other_answer");
1040  }
1041  $counter++;
1042  }
1043  }
1044  if ($counter != $this->getRowCount()) return $this->lng->txt("matrix_question_radio_button_not_checked");
1045  break;
1046  case 1:
1047  $counter = 0;
1048  foreach ($post_data as $key => $value)
1049  {
1050  if (preg_match("/matrix_" . $this->getId() . "_(\d+)/", $key, $matches))
1051  {
1052  if (array_key_exists('matrix_other_' . $this->getId() . "_" . $matches[1], $post_data) && strlen($post_data['matrix_other_' . $this->getId() . "_" . $matches[1]]) == 0)
1053  {
1054  return $this->lng->txt("question_mr_no_other_answer");
1055  }
1056  $counter++;
1057  if ((!is_array($value)) || (count($value) < 1))
1058  {
1059  return $this->lng->txt("matrix_question_checkbox_not_checked");
1060  }
1061  }
1062  }
1063  if ($counter != $this->getRowCount()) return $this->lng->txt("matrix_question_checkbox_not_checked");
1064  break;
1065  }
1066  return "";
1067  }
1068 
1074  public function saveRandomData($active_id)
1075  {
1076  global $ilDB;
1077  $columncount = $this->getColumnCount();
1078  for ($row = 0; $row < $this->getRowCount(); $row++)
1079  {
1080  if ($this->getSubType() == 1)
1081  {
1082  // multiple responses
1083  for ($i = 0; $i < $columncount; $i++)
1084  {
1085  if (rand(0,1))
1086  {
1087  $next_id = $ilDB->nextId('svy_answer');
1088  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_answer (answer_id, question_fi, active_fi, value, textanswer, rowvalue, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
1089  array('integer','integer','integer','float','text','integer','integer'),
1090  array($next_id, $this->getId(), $active_id, $i, NULL, $row, time())
1091  );
1092  }
1093  }
1094  }
1095  else
1096  {
1097  // single responses
1098  $category = rand(0, $columncount-1);
1099  $next_id = $ilDB->nextId('svy_answer');
1100  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_answer (answer_id, question_fi, active_fi, value, textanswer, rowvalue, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
1101  array('integer','integer','integer','float','text','integer','integer'),
1102  array($next_id, $this->getId(), $active_id, $category, NULL, $row, time())
1103  );
1104  }
1105  }
1106  }
1107 
1108  function saveUserInput($post_data, $active_id)
1109  {
1110  global $ilDB;
1111 
1112  switch ($this->getSubtype())
1113  {
1114  case 0:
1115  foreach ($post_data as $key => $value)
1116  {
1117  if (preg_match("/matrix_" . $this->getId() . "_(\d+)/", $key, $matches))
1118  {
1119  $next_id = $ilDB->nextId('svy_answer');
1120  $other_value = (array_key_exists('matrix_other_' . $this->getId() . '_' . $matches[1], $post_data)) ? ($post_data['matrix_other_' . $this->getId() . '_' . $matches[1]]) : null;
1121  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_answer (answer_id, question_fi, active_fi, value, textanswer, rowvalue, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
1122  array('integer','integer','integer','float','text','integer','integer'),
1123  array($next_id, $this->getId(), $active_id, $value, $other_value, $matches[1], time())
1124  );
1125  }
1126  }
1127  break;
1128  case 1:
1129  foreach ($post_data as $key => $value)
1130  {
1131  if (preg_match("/matrix_" . $this->getId() . "_(\d+)/", $key, $matches))
1132  {
1133  $other_value = (array_key_exists('matrix_other_' . $this->getId() . '_' . $matches[1], $post_data)) ? ($post_data['matrix_other_' . $this->getId() . '_' . $matches[1]]) : null;
1134  foreach ($value as $checked)
1135  {
1136  if (strlen($checked))
1137  {
1138  $next_id = $ilDB->nextId('svy_answer');
1139  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_answer (answer_id, question_fi, active_fi, value, textanswer, rowvalue, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
1140  array('integer','integer','integer','float','text','integer','integer'),
1141  array($next_id, $this->getId(), $active_id, $checked, $other_value, $matches[1], time())
1142  );
1143  }
1144  }
1145  }
1146  }
1147  break;
1148  }
1149  }
1150 
1157  function deleteAdditionalTableData($question_id)
1158  {
1159  parent::deleteAdditionalTableData($question_id);
1160 
1161  global $ilDB;
1162  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qst_matrixrows WHERE question_fi = %s",
1163  array('integer'),
1164  array($question_id)
1165  );
1166  }
1167 
1176  {
1177  global $ilDB;
1178 
1179  $result = $ilDB->queryF("SELECT svy_answer.active_fi, svy_answer.question_fi FROM svy_answer, svy_finished WHERE svy_answer.question_fi = %s AND svy_finished.survey_fi = %s AND svy_finished.finished_id = svy_answer.active_fi",
1180  array('integer', 'integer'),
1181  array($this->getId(), $survey_id)
1182  );
1183  $found = array();
1184  while ($row = $ilDB->fetchAssoc($result))
1185  {
1186  $found[$row["active_fi"].$row["question_fi"]] = 1;
1187  }
1188  return count($found);
1189  }
1190 
1199  function &getCumulatedResultsForRow($rowindex, $survey_id, $nr_of_users)
1200  {
1201  global $ilDB;
1202 
1203  $question_id = $this->getId();
1204 
1205  $result_array = array();
1206  $cumulated = array();
1207 
1208  $result = $ilDB->queryF("SELECT svy_answer.* FROM svy_answer, svy_finished WHERE svy_answer.question_fi = %s AND svy_finished.survey_fi = %s AND svy_answer.rowvalue = %s AND svy_finished.finished_id = svy_answer.active_fi",
1209  array('integer', 'integer', 'integer'),
1210  array($question_id, $survey_id, $rowindex)
1211  );
1212 
1213  switch ($this->getSubtype())
1214  {
1215  case 0:
1216  case 1:
1217  while ($row = $ilDB->fetchAssoc($result))
1218  {
1219  $cumulated[$row["value"]]++;
1220 
1221  if ($row["textanswer"])
1222  {
1223  $result_array["textanswers"][$row["value"]][] = $row["textanswer"];
1224  }
1225  }
1226  if (is_array($result_array["textanswers"]))
1227  {
1228  ksort($result_array["textanswers"], SORT_NUMERIC);
1229  }
1230  asort($cumulated, SORT_NUMERIC);
1231  end($cumulated);
1232  break;
1233  }
1234  $numrows = $result->numRows();
1235  $result_array["USERS_ANSWERED"] = $this->getNrOfUsersAnswered($survey_id);
1236  $result_array["USERS_SKIPPED"] = $nr_of_users - $this->getNrOfUsersAnswered($survey_id);
1237 
1238  $prefix = "";
1239  if (strcmp(key($cumulated), "") != 0)
1240  {
1241  $prefix = (key($cumulated)+1) . " - ";
1242  }
1243  $cat = $this->getColumnForScale(key($cumulated)+1);
1244  $result_array["MODE"] = $prefix . $cat->title;
1245  $result_array["MODE_VALUE"] = key($cumulated)+1;
1246  $result_array["MODE_NR_OF_SELECTIONS"] = $cumulated[key($cumulated)];
1247  for ($key = 0; $key < $this->getColumnCount(); $key++)
1248  {
1249  $percentage = 0;
1250  if ($numrows > 0)
1251  {
1252  $percentage = (float)((int)$cumulated[$key]/$numrows);
1253  }
1254  $cat = $this->getColumn($key);
1255  $result_array["variables"][$key] = array("title" => $cat->title, "selected" => (int)$cumulated[$key], "percentage" => $percentage);
1256  }
1257  ksort($cumulated, SORT_NUMERIC);
1258  $median = array();
1259  $total = 0;
1260  foreach ($cumulated as $value => $key)
1261  {
1262  $total += $key;
1263  for ($i = 0; $i < $key; $i++)
1264  {
1265  array_push($median, $value+1);
1266  }
1267  }
1268  if ($total > 0)
1269  {
1270  if (($total % 2) == 0)
1271  {
1272  $median_value = 0.5 * ($median[($total/2)-1] + $median[($total/2)]);
1273  if (round($median_value) != $median_value)
1274  {
1275  $cat = $this->getColumnForScale((int)floor($median_value));
1276  $cat2 = $this->getColumnForScale((int)ceil($median_value));
1277  $median_value = $median_value . "<br />" . "(" . $this->lng->txt("median_between") . " " . (floor($median_value)) . "-" . $cat->title . " " . $this->lng->txt("and") . " " . (ceil($median_value)) . "-" . $cat2->title . ")";
1278  }
1279  }
1280  else
1281  {
1282  $median_value = $median[(($total+1)/2)-1];
1283  }
1284  }
1285  else
1286  {
1287  $median_value = "";
1288  }
1289  $result_array["ARITHMETIC_MEAN"] = "";
1290  $result_array["MEDIAN"] = $median_value;
1291  $result_array["QUESTION_TYPE"] = "SurveyMatrixQuestion";
1292  $result_array["ROW"] = $this->getRow($rowindex)->title;
1293  return $result_array;
1294  }
1295 
1303  function &getCumulatedResults($survey_id, $nr_of_users)
1304  {
1305  global $ilDB;
1306 
1307  $question_id = $this->getId();
1308 
1309  $result_array = array();
1310  $cumulated = array();
1311 
1312  $result = $ilDB->queryF("SELECT svy_answer.* FROM svy_answer, svy_finished WHERE svy_answer.question_fi = %s AND svy_finished.survey_fi = %s AND svy_finished.finished_id = svy_answer.active_fi",
1313  array('integer', 'integer'),
1314  array($question_id, $survey_id)
1315  );
1316 
1317  switch ($this->getSubtype())
1318  {
1319  case 0:
1320  case 1:
1321  while ($row = $ilDB->fetchAssoc($result))
1322  {
1323  $cumulated[$row["value"]]++;
1324  }
1325  asort($cumulated, SORT_NUMERIC);
1326  end($cumulated);
1327  break;
1328  }
1329  $numrows = $result->numRows();
1330  $result_array["USERS_ANSWERED"] = $this->getNrOfUsersAnswered($survey_id);
1331  $result_array["USERS_SKIPPED"] = $nr_of_users - $this->getNrOfUsersAnswered($survey_id);
1332 
1333  $prefix = "";
1334  if (strcmp(key($cumulated), "") != 0)
1335  {
1336  $prefix = (key($cumulated)+1) . " - ";
1337  }
1338  $cat = $this->getColumnForScale(key($cumulated)+1);
1339  $result_array["MODE"] = $prefix . $cat->title;
1340  $result_array["MODE_VALUE"] = key($cumulated)+1;
1341  $result_array["MODE_NR_OF_SELECTIONS"] = $cumulated[key($cumulated)];
1342  for ($key = 0; $key < $this->getColumnCount(); $key++)
1343  {
1344  $percentage = 0;
1345  if ($numrows > 0)
1346  {
1347  $percentage = (float)((int)$cumulated[$key]/$numrows);
1348  }
1349  $cat = $this->getColumn($key);
1350  $result_array["variables"][$key] = array("title" => $cat->title, "selected" => (int)$cumulated[$key], "percentage" => $percentage);
1351  }
1352  ksort($cumulated, SORT_NUMERIC);
1353  $median = array();
1354  $total = 0;
1355  foreach ($cumulated as $value => $key)
1356  {
1357  $total += $key;
1358  for ($i = 0; $i < $key; $i++)
1359  {
1360  array_push($median, $value+1);
1361  }
1362  }
1363  if ($total > 0)
1364  {
1365  if (($total % 2) == 0)
1366  {
1367  $median_value = 0.5 * ($median[($total/2)-1] + $median[($total/2)]);
1368  if (round($median_value) != $median_value)
1369  {
1370  $cat = $this->getColumnForScale((int)floor($median_value));
1371  $cat2 = $this->getColumnForScale((int)ceil($median_value));
1372  $median_value = $median_value . "<br />" . "(" . $this->lng->txt("median_between") . " " . (floor($median_value)) . "-" . $cat->title . " " . $this->lng->txt("and") . " " . (ceil($median_value)) . "-" . $cat2->title . ")";
1373  }
1374  }
1375  else
1376  {
1377  $median_value = $median[(($total+1)/2)-1];
1378  }
1379  }
1380  else
1381  {
1382  $median_value = "";
1383  }
1384  $result_array["ARITHMETIC_MEAN"] = "";
1385  $result_array["MEDIAN"] = $median_value;
1386  $result_array["QUESTION_TYPE"] = "SurveyMatrixQuestion";
1387 
1388  $cumulated_results = array();
1389  $cumulated_results["TOTAL"] = $result_array;
1390  for ($i = 0; $i < $this->getRowCount(); $i++)
1391  {
1392  $rowresult =& $this->getCumulatedResultsForRow($i, $survey_id, $nr_of_users);
1393  $cumulated_results[$i] = $rowresult;
1394  }
1395  return $cumulated_results;
1396  }
1397 
1407  function setExportCumulatedXLS(&$adapter, &$eval_data, $row, $export_label)
1408  {
1409  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
1410  $column = 0;
1411  switch ($export_label)
1412  {
1413  case 'label_only':
1414  $adapter->setCellValue($row, $column, $this->label);
1415  break;
1416  case 'title_only':
1417  $adapter->setCellValue($row, $column, $this->getTitle());
1418  break;
1419  default:
1420  $adapter->setCellValue($row, $column, $this->getTitle());
1421  $column++;
1422  $adapter->setCellValue($row, $column, $this->label);
1423  break;
1424  }
1425  $column++;
1426  $adapter->setCellValue($row, $column, $this->getQuestiontext());
1427  $column++;
1428  $adapter->setCellValue($row, $column, $this->lng->txt($eval_data["TOTAL"]["QUESTION_TYPE"]));
1429  $column++;
1430  $adapter->setCellValue($row, $column, $eval_data["TOTAL"]["USERS_ANSWERED"]);
1431  $column++;
1432  $adapter->setCellValue($row, $column, $eval_data["TOTAL"]["USERS_SKIPPED"]);
1433  $column++;
1434  $adapter->setCellValue($row, $column, $eval_data["TOTAL"]["MODE_VALUE"]);
1435  $column++;
1436  $adapter->setCellValue($row, $column, $eval_data["TOTAL"]["MODE"]);
1437  $column++;
1438  $adapter->setCellValue($row, $column, $eval_data["TOTAL"]["MODE_NR_OF_SELECTIONS"]);
1439  $column++;
1440  $adapter->setCellValue($row, $column, str_replace("<br />", " ", $eval_data["TOTAL"]["MEDIAN"]));
1441  $column++;
1442  $adapter->setCellValue($row, $column, $eval_data["TOTAL"]["ARITHMETIC_MEAN"]);
1443  $row++;
1444  $add = 0;
1445  switch ($export_label)
1446  {
1447  case 'label_only':
1448  case 'title_only':
1449  break;
1450  default:
1451  $add = 1;
1452  break;
1453  }
1454  foreach ($eval_data as $evalkey => $evalvalue)
1455  {
1456  if (is_numeric($evalkey))
1457  {
1458  $adapter->setCellValue($row, 1+$add, $evalvalue["ROW"]);
1459  $adapter->setCellValue($row, 3+$add, $evalvalue["USERS_ANSWERED"]);
1460  $adapter->setCellValue($row, 4+$add, $evalvalue["USERS_SKIPPED"]);
1461  $adapter->setCellValue($row, 5+$add, $evalvalue["MODE_VALUE"]);
1462  $adapter->setCellValue($row, 6+$add, $evalvalue["MODE"]);
1463  $adapter->setCellValue($row, 7+$add, $evalvalue["MODE_NR_OF_SELECTIONS"]);
1464  $adapter->setCellValue($row, 8+$add, str_replace("<br />", " ", $evalvalue["MEDIAN"]));
1465  $adapter->setCellValue($row, 9+$add, $evalvalue["ARITHMETIC_MEAN"]);
1466  $row++;
1467  }
1468  }
1469  return $row;
1470  }
1471 
1479  function &setExportCumulatedCVS(&$eval_data, $export_label)
1480  {
1481  $result = array();
1482  foreach ($eval_data as $evalkey => $evalvalue)
1483  {
1484  $csvrow = array();
1485  if (is_numeric($evalkey))
1486  {
1487  array_push($csvrow, "");
1488  array_push($csvrow, $evalvalue["ROW"]);
1489  array_push($csvrow, "");
1490  }
1491  else
1492  {
1493  switch ($export_label)
1494  {
1495  case 'label_only':
1496  array_push($csvrow, $this->label);
1497  break;
1498  case 'title_only':
1499  array_push($csvrow, $this->getTitle());
1500  break;
1501  default:
1502  array_push($csvrow, $this->getTitle());
1503  array_push($csvrow, $this->label);
1504  break;
1505  }
1506  array_push($csvrow, $this->getQuestiontext());
1507  array_push($csvrow, $this->lng->txt($evalvalue["QUESTION_TYPE"]));
1508  }
1509  array_push($csvrow, $evalvalue["USERS_ANSWERED"]);
1510  array_push($csvrow, $evalvalue["USERS_SKIPPED"]);
1511  array_push($csvrow, $evalvalue["MODE"]);
1512  array_push($csvrow, $evalvalue["MODE_NR_OF_SELECTIONS"]);
1513  array_push($csvrow, $evalvalue["MEDIAN"]);
1514  array_push($csvrow, $evalvalue["ARITHMETIC_MEAN"]);
1515  array_push($result, $csvrow);
1516  }
1517  return $result;
1518  }
1519 
1527  function setExportDetailsXLS(&$adapter, &$eval_data, $export_label)
1528  {
1529  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
1530  $adapter->addWorksheet($this->getTitle());
1531  $adapter->setActiveWorksheet($adapter->getWorksheetCount()-1);
1532  $rowcounter = 0;
1533  switch ($export_label)
1534  {
1535  case 'label_only':
1536  $adapter->setCellValue(0, 0, $this->lng->txt("label"), CELL_FORMAT_BOLD);
1537  $adapter->setCellValue(0, 1, $this->label);
1538  break;
1539  case 'title_only':
1540  $adapter->setCellValue(0, 0, $this->lng->txt("title"), CELL_FORMAT_BOLD);
1541  $adapter->setCellValue(0, 1, $this->getTitle());
1542  break;
1543  default:
1544  $adapter->setCellValue(0, 0, $this->lng->txt("title"), CELL_FORMAT_BOLD);
1545  $adapter->setCellValue(0, 1, $this->getTitle());
1546  $rowcounter++;
1547  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("label"), CELL_FORMAT_BOLD);
1548  $adapter->setCellValue($rowcounter, 1, $this->label);
1549  break;
1550  }
1551  $rowcounter++;
1552  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("question"), CELL_FORMAT_BOLD);
1553  $adapter->setCellValue($rowcounter, 1, $this->getQuestiontext());
1554  $rowcounter++;
1555  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("question_type"), CELL_FORMAT_BOLD);
1556  $adapter->setCellValue($rowcounter, 1, $this->lng->txt($this->getQuestionType()));
1557  $rowcounter++;
1558  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("users_answered"), CELL_FORMAT_BOLD);
1559  $adapter->setCellValue($rowcounter, 1, $eval_data["TOTAL"]["USERS_ANSWERED"]);
1560  $rowcounter++;
1561  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("users_skipped"), CELL_FORMAT_BOLD);
1562  $adapter->setCellValue($rowcounter, 1, $eval_data["TOTAL"]["USERS_SKIPPED"]);
1563  $rowcounter++;
1564 
1565  preg_match("/(.*?)\s+-\s+(.*)/", $eval_data["TOTAL"]["MODE"], $matches);
1566  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("mode"), CELL_FORMAT_BOLD);
1567  $adapter->setCellValue($rowcounter++, 1, $matches[1]);
1568  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("mode_text"), CELL_FORMAT_BOLD);
1569  $adapter->setCellValue($rowcounter++, 1, $matches[2]);
1570  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("mode_nr_of_selections"), CELL_FORMAT_BOLD);
1571  $adapter->setCellValue($rowcounter++, 1, $eval_data["TOTAL"]["MODE_NR_OF_SELECTIONS"]);
1572  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("median"), CELL_FORMAT_BOLD);
1573  $adapter->setCellValue($rowcounter++, 1, str_replace("<br />", " ", $eval_data["TOTAL"]["MEDIAN"]));
1574  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("categories"), CELL_FORMAT_BOLD);
1575  $adapter->setCellValue($rowcounter, 1, $this->lng->txt("title"), CELL_FORMAT_TITLE);
1576  $adapter->setCellValue($rowcounter, 2, $this->lng->txt("value"), CELL_FORMAT_TITLE);
1577  $adapter->setCellValue($rowcounter, 3, $this->lng->txt("category_nr_selected"), CELL_FORMAT_TITLE);
1578  $adapter->setCellValue($rowcounter++, 4, $this->lng->txt("percentage_of_selections"), CELL_FORMAT_TITLE);
1579 
1580  foreach ($eval_data["TOTAL"]["variables"] as $key => $value)
1581  {
1582  $adapter->setCellValue($rowcounter, 1, $value["title"]);
1583  $adapter->setCellValue($rowcounter, 2, $key+1);
1584  $adapter->setCellValue($rowcounter, 3, $value["selected"]);
1585  $adapter->setCellValue($rowcounter++, 4, $value["percentage"], CELL_FORMAT_PERCENT);
1586  }
1587 
1588  foreach ($eval_data as $evalkey => $evalvalue)
1589  {
1590  if (is_numeric($evalkey))
1591  {
1592  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("row"), CELL_FORMAT_BOLD);
1593  $adapter->setCellValue($rowcounter, 1, $evalvalue["ROW"]);
1594  $adapter->setCellValue($rowcounter + 1, 0, $this->lng->txt("users_answered"), CELL_FORMAT_BOLD);
1595  $adapter->setCellValue($rowcounter + 1, 1, $evalvalue["USERS_ANSWERED"]);
1596  $adapter->setCellValue($rowcounter + 2, 0, $this->lng->txt("users_skipped"), CELL_FORMAT_BOLD);
1597  $adapter->setCellValue($rowcounter + 2, 1, $evalvalue["USERS_SKIPPED"]);
1598  $rowcounter = $rowcounter + 3;
1599 
1600  preg_match("/(.*?)\s+-\s+(.*)/", $evalvalue["MODE"], $matches);
1601  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("mode"), CELL_FORMAT_BOLD);
1602  $adapter->setCellValue($rowcounter++, 1, $matches[1]);
1603  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("mode_text"), CELL_FORMAT_BOLD);
1604  $adapter->setCellValue($rowcounter++, 1, $matches[2]);
1605  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("mode_nr_of_selections"), CELL_FORMAT_BOLD);
1606  $adapter->setCellValue($rowcounter++, 1, $evalvalue["MODE_NR_OF_SELECTIONS"]);
1607  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("median"), CELL_FORMAT_BOLD);
1608  $adapter->setCellValue($rowcounter++, 1, str_replace("<br />", " ", $evalvalue["MEDIAN"]));
1609  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("categories"), CELL_FORMAT_BOLD);
1610  $adapter->setCellValue($rowcounter, 1, $this->lng->txt("title"), CELL_FORMAT_TITLE);
1611  $adapter->setCellValue($rowcounter, 2, $this->lng->txt("value"), CELL_FORMAT_TITLE);
1612  $adapter->setCellValue($rowcounter, 3, $this->lng->txt("category_nr_selected"), CELL_FORMAT_TITLE);
1613  $adapter->setCellValue($rowcounter++, 4, $this->lng->txt("percentage_of_selections"), CELL_FORMAT_TITLE);
1614 
1615  foreach ($evalvalue["variables"] as $key => $value)
1616  {
1617  $adapter->setCellValue($rowcounter, 1, $value["title"]);
1618  $adapter->setCellValue($rowcounter, 2, $key+1);
1619  $adapter->setCellValue($rowcounter, 3, $value["selected"]);
1620  $adapter->setCellValue($rowcounter++, 4, $value["percentage"], CELL_FORMAT_PERCENT);
1621  }
1622 
1623  if (is_array($evalvalue["textanswers"]))
1624  {
1625  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("freetext_answers"), CELL_FORMAT_BOLD);
1626  $adapter->setCellValue($rowcounter, 1, $this->lng->txt("title"), CELL_FORMAT_TITLE);
1627  $adapter->setCellValue($rowcounter++, 2, $this->lng->txt("answer"), CELL_FORMAT_TITLE);
1628 
1629  foreach ($evalvalue["textanswers"] as $key => $answers)
1630  {
1631  $title = $evalvalue["variables"][$key]["title"];
1632  foreach ($answers as $answer)
1633  {
1634  $adapter->setCellValue($rowcounter, 1, $title);
1635  $adapter->setCellValue($rowcounter++, 2, $answer);
1636  }
1637  }
1638  }
1639  }
1640  }
1641  $adapter->setCellValue($rowcounter, 0, $this->lng->txt("overview"), CELL_FORMAT_BOLD);
1642  // title row with variables
1643  $rowcounter++;
1644  $counter = 0;
1645  $adapter->setCellValue($rowcounter, $counter, "", CELL_FORMAT_TITLE);
1646  foreach ($eval_data["TOTAL"]["variables"] as $variable)
1647  {
1648  $adapter->setCellValue($rowcounter, 1+$counter, $variable["title"], CELL_FORMAT_TITLE);
1649  $counter++;
1650  }
1651  $rowcounter++;
1652  // rows with variable values
1653  foreach ($eval_data as $index => $data)
1654  {
1655  if (is_numeric($index))
1656  {
1657  $adapter->setCellValue($rowcounter, 0, $data["ROW"], CELL_FORMAT_TITLE);
1658  $counter = 1;
1659  foreach ($data["variables"] as $vardata)
1660  {
1661  $adapter->setCellValue($rowcounter, $counter, $vardata["selected"], CELL_FORMAT_CENTER);
1662  $counter++;
1663  }
1664  $rowcounter++;
1665  }
1666  }
1667  }
1668 
1675  function addUserSpecificResultsExportTitles(&$a_array, $a_export_label = "")
1676  {
1677  parent::addUserSpecificResultsExportTitles($a_array, $a_export_label);
1678 
1679  for ($i = 0; $i < $this->getRowCount(); $i++)
1680  {
1681  // create row title according label, add 'other column'
1682  $row = $this->getRow($i);
1683  switch ($a_export_label)
1684  {
1685  case "label_only":
1686  $title = $row->label ? $row->label : $row->title;
1687  break;
1688 
1689  case "title_only":
1690  $title = $row->title;
1691  break;
1692 
1693  default:
1694  $title = $row->label ? $row->title." - ".$row->label : $row->title;
1695  break;
1696  }
1697  array_push($a_array, $title);
1698 
1699  if ($row->other)
1700  {
1701  array_push($a_array, $title. ' - '. $this->lng->txt('other'));
1702  }
1703 
1704  switch ($this->getSubtype())
1705  {
1706  case 0:
1707  break;
1708  case 1:
1709  for ($index = 0; $index < $this->getColumnCount(); $index++)
1710  {
1711  $col = $this->getColumn($index);
1712  array_push($a_array, ($index+1) . " - " . $col->title);
1713  }
1714  break;
1715  }
1716  }
1717  }
1718 
1726  function addUserSpecificResultsData(&$a_array, &$resultset)
1727  {
1728  if (count($resultset["answers"][$this->getId()]))
1729  {
1730  array_push($a_array, "");
1731  switch ($this->getSubtype())
1732  {
1733  case 0:
1734  for ($i = 0; $i < $this->getRowCount(); $i++)
1735  {
1736  $row = $this->getRow($i);
1737  $textanswer = "";
1738  $checked = FALSE;
1739  foreach ($resultset["answers"][$this->getId()] as $result)
1740  {
1741  if ($result["rowvalue"] == $i)
1742  {
1743  $checked = TRUE;
1744  array_push($a_array, $result["value"] + 1);
1745  if ($result["textanswer"])
1746  {
1747  $textanswer = $result["textanswer"];
1748  }
1749  }
1750  }
1751  if (!$checked)
1752  {
1753  array_push($a_array, $this->lng->txt("skipped"));
1754  }
1755  // add textanswer column for single choice mode
1756  if ($row->other)
1757  {
1758  array_push($a_array, $textanswer);
1759  }
1760  }
1761  break;
1762  case 1:
1763  for ($i = 0; $i < $this->getRowCount(); $i++)
1764  {
1765  $row = $this->getRow($i);
1766  $textanswer = "";
1767  $checked = FALSE;
1768  $checked_values = array();
1769  foreach ($resultset["answers"][$this->getId()] as $result)
1770  {
1771  if ($result["rowvalue"] == $i)
1772  {
1773  $checked = TRUE;
1774  array_push($checked_values, $result["value"] + 1);
1775  if ($result["textanswer"])
1776  {
1777  $textanswer = $result["textanswer"];
1778  }
1779  }
1780  }
1781  if (!$checked)
1782  {
1783  array_push($a_array, $this->lng->txt("skipped"));
1784  }
1785  else
1786  {
1787  array_push($a_array, "");
1788  }
1789  // add textanswer column for multiple choice mode
1790  if ($row->other)
1791  {
1792  array_push($a_array, $textanswer);
1793  }
1794  for ($index = 0; $index < $this->getColumnCount(); $index++)
1795  {
1796  if (!$checked)
1797  {
1798  array_push($a_array, "");
1799  }
1800  else
1801  {
1802  if (in_array($index+1, $checked_values))
1803  {
1804  array_push($a_array, 1);
1805  }
1806  else
1807  {
1808  array_push($a_array, 0);
1809  }
1810  }
1811  }
1812  }
1813  break;
1814  }
1815  }
1816  else
1817  {
1818  array_push($a_array, $this->lng->txt("skipped"));
1819  for ($i = 0; $i < $this->getRowCount(); $i++)
1820  {
1821  array_push($a_array, "");
1822 
1823  // add empty "other" column if not answered
1824  $row = $this->getRow($i);
1825  if ($row->other)
1826  {
1827  array_push($a_array, "");
1828  }
1829 
1830  switch ($this->getSubtype())
1831  {
1832  case 0:
1833  break;
1834  case 1:
1835  for ($index = 0; $index < $this->getColumnCount(); $index++)
1836  {
1837  array_push($a_array, "");
1838  }
1839  break;
1840  }
1841  }
1842  }
1843  }
1844 
1853  {
1854  global $ilDB;
1855 
1856  $answers = array();
1857 
1858  $result = $ilDB->queryF("SELECT svy_answer.* FROM svy_answer, svy_finished WHERE svy_finished.survey_fi = %s AND svy_answer.question_fi = %s AND svy_finished.finished_id = svy_answer.active_fi ORDER BY rowvalue, value",
1859  array('integer','integer'),
1860  array($survey_id, $this->getId())
1861  );
1862  $results = array();
1863  while ($row = $ilDB->fetchAssoc($result))
1864  {
1865  $column = $this->getColumn($row["value"]);
1866  if (!is_array($answers[$row["active_fi"]])) $answers[$row["active_fi"]] = array();
1867  $rowobj = $this->getRow($row["rowvalue"]);
1868  array_push($answers[$row["active_fi"]], $rowobj->title . (($rowobj->other) ? (" " . $row["textanswer"]) : "") . ": " . ($row["value"] + 1) . " - " . $column->title);
1869  }
1870  foreach ($answers as $key => $value)
1871  {
1872  $answers[$key] = implode("<br />", $value);
1873  }
1874  return $answers;
1875  }
1876 
1883  function getSubtype()
1884  {
1885  return $this->subtype;
1886  }
1887 
1894  function setSubtype($a_subtype = 0)
1895  {
1896  switch ($a_subtype)
1897  {
1898  case 1:
1899  case 2:
1900  case 3:
1901  case 4:
1902  case 5:
1903  case 6:
1904  $this->subtype = $a_subtype;
1905  break;
1906  case 0:
1907  default:
1908  $this->subtype = 0;
1909  break;
1910  }
1911  }
1912 
1919  function setColumnSeparators($enable = 0)
1920  {
1921  switch ($enable)
1922  {
1923  case 1:
1924  $this->columnSeparators = 1;
1925  break;
1926  case 0:
1927  default:
1928  $this->columnSeparators = 0;
1929  break;
1930  }
1931  }
1932 
1940  {
1941  return ($this->columnSeparators) ? 1 : 0;
1942  }
1943 
1950  function setRowSeparators($enable = 0)
1951  {
1952  switch ($enable)
1953  {
1954  case 1:
1955  $this->rowSeparators = 1;
1956  break;
1957  case 0:
1958  default:
1959  $this->rowSeparators = 0;
1960  break;
1961  }
1962  }
1963 
1970  function getRowSeparators()
1971  {
1972  return ($this->rowSeparators) ? 1 : 0;
1973  }
1974 
1981  function setNeutralColumnSeparator($enable = 0)
1982  {
1983  switch ($enable)
1984  {
1985  case 1:
1986  $this->neutralColumnSeparator = 1;
1987  break;
1988  case 0:
1989  default:
1990  $this->neutralColumnSeparator = 0;
1991  break;
1992  }
1993  }
1994 
2002  {
2003  return ($this->neutralColumnSeparator) ? 1 : 0;
2004  }
2005 
2014  function importAdditionalMetadata($a_meta)
2015  {
2016  foreach ($a_meta as $key => $value)
2017  {
2018  switch ($value["label"])
2019  {
2020  case "column_separators":
2021  $this->setColumnSeparators($value["entry"]);
2022  break;
2023  case "row_separators":
2024  $this->setRowSeparators($value["entry"]);
2025  break;
2026  case "layout":
2027  $this->setLayout($value["entry"]);
2028  break;
2029  case "neutral_column_separator":
2030  $this->setNeutralColumnSeparator($value["entry"]);
2031  break;
2032  }
2033  }
2034  }
2035 
2042  function importAdjectives($a_data)
2043  {
2044  $i = 0;
2045  foreach ($a_data as $adjective)
2046  {
2047  if (is_numeric($adjective["label"]))
2048  {
2049  $this->setBipolarAdjective($adjective["label"], $adjective["text"]);
2050  }
2051  else
2052  {
2053  $this->setBipolarAdjective($i, $adjective["text"]);
2054  }
2055  $i++;
2056  }
2057  }
2058 
2065  function importMatrix($a_data)
2066  {
2067  foreach ($a_data as $row)
2068  {
2069  $this->addRow($row['title'], $row['other'], $row['label']);
2070  }
2071  }
2072 
2079  function importResponses($a_data)
2080  {
2081  foreach ($a_data as $id => $data)
2082  {
2083  $column = "";
2084  foreach ($data["material"] as $material)
2085  {
2086  $column .= $material["text"];
2087  }
2088  $this->columns->addCategory($column, null, (strcmp($data["label"], "neutral") == 0) ? true : false);
2089  }
2090  }
2091 
2099  {
2100  return FALSE;
2101  }
2102 
2111  {
2112  return $value;
2113  }
2114 
2121  public function getPreconditionSelectValue($default = "", $title, $variable)
2122  {
2123  include_once "./Services/Form/classes/class.ilSelectInputGUI.php";
2124  $step3 = new ilSelectInputGUI($title, $variable);
2125  $options = $this->getPreconditionOptions();
2126  $step3->setOptions($options);
2127  $step3->setValue($default);
2128  return $step3;
2129  }
2130 
2139  function outChart($survey_id, $type = "")
2140  {
2141  if (count($this->cumulated) == 0)
2142  {
2143  include_once "./Modules/Survey/classes/class.ilObjSurvey.php";
2145  $this->cumulated =& $this->getCumulatedResults($survey_id, $nr_of_users);
2146  }
2147  global $ilLog;
2148  if (is_numeric($type))
2149  {
2150  foreach ($this->cumulated[$type]["variables"] as $key => $value)
2151  {
2152  foreach ($value as $key2 => $value2)
2153  {
2154  $this->cumulated["variables"][$key][$key2] = utf8_decode($value2);
2155  }
2156  }
2157  $title = preg_replace("/<[^>]+?>/ims", "", $this->getRow($type)->title);
2158  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyChart.php";
2159  $b1 = new SurveyChart("bars", 400, 250, utf8_decode($title),utf8_decode($this->lng->txt("answers")), utf8_decode($this->lng->txt("users_answered")), $this->cumulated[$type]["variables"]);
2160  }
2161  }
2162 
2172  function saveLayout($percent_row, $percent_columns, $percent_bipolar_adjective1 = "", $percent_bipolar_adjective2 = "", $percent_neutral)
2173  {
2174  global $ilDB;
2175 
2176  $layout = array(
2177  "percent_row" => $percent_row,
2178  "percent_columns" => $percent_columns,
2179  "percent_bipolar_adjective1" => $percent_bipolar_adjective1,
2180  "percent_bipolar_adjective2" => $percent_bipolar_adjective2,
2181  "percent_neutral" => $percent_neutral
2182  );
2183  $affectedRows = $ilDB->manipulateF("UPDATE " . $this->getAdditionalTableName() . " SET layout = %s WHERE question_fi = %s",
2184  array('text', 'integer'),
2185  array(serialize($layout), $this->getId())
2186  );
2187  }
2188 
2189  function getLayout()
2190  {
2191  if (!is_array($this->layout) || count($this->layout) == 0)
2192  {
2193  if ($this->hasBipolarAdjectives() && $this->hasNeutralColumn())
2194  {
2195  $this->layout = array(
2196  "percent_row" => 30,
2197  "percent_columns" => 40,
2198  "percent_bipolar_adjective1" => 10,
2199  "percent_bipolar_adjective2" => 10,
2200  "percent_neutral" => 10
2201  );
2202  }
2203  elseif ($this->hasBipolarAdjectives())
2204  {
2205  $this->layout = array(
2206  "percent_row" => 30,
2207  "percent_columns" => 50,
2208  "percent_bipolar_adjective1" => 10,
2209  "percent_bipolar_adjective2" => 10,
2210  "percent_neutral" => 0
2211  );
2212  }
2213  elseif ($this->hasNeutralColumn())
2214  {
2215  $this->layout = array(
2216  "percent_row" => 30,
2217  "percent_columns" => 50,
2218  "percent_bipolar_adjective1" => 0,
2219  "percent_bipolar_adjective2" => 0,
2220  "percent_neutral" => 20
2221  );
2222  }
2223  else
2224  {
2225  $this->layout = array(
2226  "percent_row" => 30,
2227  "percent_columns" => 70,
2228  "percent_bipolar_adjective1" => 0,
2229  "percent_bipolar_adjective2" => 0,
2230  "percent_neutral" => 0
2231  );
2232  }
2233  }
2234  return $this->layout;
2235  }
2236 
2237  function setLayout($layout)
2238  {
2239  if (is_array($layout))
2240  {
2241  $this->layout = $layout;
2242  }
2243  else
2244  {
2245  $this->layout = unserialize($layout);
2246  }
2247  }
2248 
2255  {
2256  if ((strlen($this->getBipolarAdjective(0))) && (strlen($this->getBipolarAdjective(1))))
2257  {
2258  return TRUE;
2259  }
2260  else
2261  {
2262  return FALSE;
2263  }
2264  }
2265 
2271  function hasNeutralColumn()
2272  {
2273  foreach ($this->columns as $column)
2274  {
2275  if ($column->neutral && strlen($column->title)) return true;
2276  }
2277  return FALSE;
2278  }
2279 
2285  function setColumnPlaceholders($a_value = 0)
2286  {
2287  $this->columnPlaceholders = ($a_value) ? 1 : 0;
2288  }
2289 
2296  {
2297  return ($this->columnPlaceholders) ? 1 : 0;
2298  }
2299 
2305  function setLegend($a_value = 0)
2306  {
2307  $this->legend = ($a_value) ? 1 : 0;
2308  }
2309 
2315  function getLegend()
2316  {
2317  return ($this->legend) ? 1 : 0;
2318  }
2319 
2320  function setSingleLineRowCaption($a_value = 0)
2321  {
2322  $this->singleLineRowCaption = ($a_value) ? 1 : 0;
2323  }
2324 
2326  {
2327  return ($this->singleLineRowCaption) ? 1 : 0;
2328  }
2329 
2330  function setRepeatColumnHeader($a_value = 0)
2331  {
2332  $this->repeatColumnHeader = ($a_value) ? 1 : 0;
2333  }
2334 
2336  {
2337  return ($this->repeatColumnHeader) ? 1 : 0;
2338  }
2339 
2340  function setColumnHeaderPosition($a_value)
2341  {
2342  $this->columnHeaderPosition = $a_value;
2343  }
2344 
2346  {
2347  return ($this->columnHeaderPosition) ? $this->columnHeaderPosition : 0;
2348  }
2349 
2350  function setRandomRows($a_value = 0)
2351  {
2352  $this->randomRows = ($a_value) ? 1 : 0;
2353  }
2354 
2355  function getRandomRows()
2356  {
2357  return ($this->randomRows) ? 1 : 0;
2358  }
2359 
2360  function setColumnOrder($a_value)
2361  {
2362  $this->columnOrder = $a_value;
2363  }
2364 
2365  function getColumnOrder()
2366  {
2367  return ($this->columnOrder) ? $this->columnOrder : 0;
2368  }
2369 
2370  function setColumnImages($a_value = 0)
2371  {
2372  $this->columnImages = ($a_value) ? 1 : 0;
2373  }
2374 
2375  function getColumnImages()
2376  {
2377  return ($this->columnImages) ? 1 : 0;
2378  }
2379 
2380  function setRowImages($a_value = 0)
2381  {
2382  $this->rowImages = ($a_value) ? 1 : 0;
2383  }
2384 
2385  function getRowImages()
2386  {
2387  return ($this->rowImages) ? 1 : 0;
2388  }
2389 
2390  public function getRows()
2391  {
2392  return $this->rows;
2393  }
2394 
2400  public function getCumulatedResultData($survey_id, $counter)
2401  {
2403  $questiontext = preg_replace("/<[^>]+?>/ims", "", $this->getQuestiontext());
2404  $maxlen = 37;
2405  if (strlen($questiontext) > $maxlen + 3)
2406  {
2407  include_once "./Services/Utilities/classes/class.ilStr.php";
2408  $questiontext = ilStr::substr($questiontext, 0, $maxlen) . "...";
2409  }
2410  $result = array();
2411  $row = array(
2412  'counter' => $counter,
2413  'title' => $this->getTitle(),
2414  'question' => $questiontext,
2415  'users_answered' => $cumulated['TOTAL']['USERS_ANSWERED'],
2416  'users_skipped' => $cumulated['TOTAL']['USERS_SKIPPED'],
2417  'question_type' => $this->lng->txt($cumulated['TOTAL']['QUESTION_TYPE']),
2418  'mode' => $cumulated['TOTAL']['MODE'],
2419  'mode_nr_of_selections' => $cumulated['TOTAL']['MODE_NR_OF_SELECTIONS'],
2420  'median' => $cumulated['TOTAL']['MEDIAN'],
2421  'arithmetic_mean' => $cumulated['TOTAL']['ARITHMETIC_MEAN']
2422  );
2423  array_push($result, $row);
2424  foreach ($cumulated as $key => $value)
2425  {
2426  if (is_numeric($key))
2427  {
2428  $row = array(
2429  'title' => '',
2430  'question' => ($key+1) . ". " . $value['ROW'],
2431  'users_answered' => $value['USERS_ANSWERED'],
2432  'users_skipped' => $value['USERS_SKIPPED'],
2433  'question_type' => '',
2434  'mode' => $value["MODE"],
2435  'mode_nr_of_selections' => $value["MODE_NR_OF_SELECTIONS"],
2436  'median' => $value["MEDIAN"],
2437  'arithmetic_mean' => $value["ARITHMETIC_MEAN"]
2438  );
2439  array_push($result, $row);
2440  }
2441  }
2442  return $result;
2443  }
2444 }
2445 ?>