ILIAS  release_4-3 Revision
 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 
222  function removeColumnWithName($name)
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 
260  function getColumnIndex($name)
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  $neutral = $row["neutral"];
424  if (($row["defaultvalue"] == 1) && ($row["owner_fi"] == 0))
425  {
426  $this->columns->addCategory($this->lng->txt($row["title"]), 0, $neutral);
427  }
428  else
429  {
430  $this->columns->addCategory($row["title"], 0, $neutral);
431  }
432  }
433  }
434 
443  {
444  global $ilDB;
445 
446  $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",
447  array('integer'),
448  array($id)
449  );
450  if ($result->numRows() == 1)
451  {
452  return $ilDB->fetchAssoc($result);
453  }
454  else
455  {
456  return array();
457  }
458  }
459 
466  function loadFromDb($id)
467  {
468  global $ilDB;
469  $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",
470  array('integer'),
471  array($id)
472  );
473  if ($result->numRows() == 1)
474  {
475  $data = $ilDB->fetchAssoc($result);
476  $this->setId($data["question_id"]);
477  $this->setTitle($data["title"]);
478  $this->label = $data['label'];
479  $this->setDescription($data["description"]);
480  $this->setObjId($data["obj_fi"]);
481  $this->setAuthor($data["author"]);
482  $this->setOwner($data["owner_fi"]);
483  include_once("./Services/RTE/classes/class.ilRTE.php");
484  $this->setQuestiontext(ilRTE::_replaceMediaObjectImageSrc($data["questiontext"], 1));
485  $this->setObligatory($data["obligatory"]);
486  $this->setComplete($data["complete"]);
487  $this->setOriginalId($data["original_id"]);
488  $this->setSubtype($data["subtype"]);
489  $this->setRowSeparators($data["row_separators"]);
490  $this->setNeutralColumnSeparator($data["neutral_column_separator"]);
491  $this->setColumnSeparators($data["column_separators"]);
492  $this->setColumnPlaceholders($data["column_placeholders"]);
493  $this->setLegend($data["legend"]);
494  $this->setSingleLineRowCaption($data["singleline_row_caption"]);
495  $this->setRepeatColumnHeader($data["repeat_column_header"]);
496  $this->setColumnHeaderPosition($data["column_header_position"]);
497  $this->setRandomRows($data["random_rows"]);
498  $this->setColumnOrder($data["column_order"]);
499  $this->setColumnImages($data["column_images"]);
500  $this->setRowImages($data["row_images"]);
501  $this->setBipolarAdjective(0, $data["bipolar_adjective1"]);
502  $this->setBipolarAdjective(1, $data["bipolar_adjective2"]);
503  $this->setLayout($data["layout"]);
504  $this->flushColumns();
505 
506  $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",
507  array('integer'),
508  array($id)
509  );
510  if ($result->numRows() > 0)
511  {
512  while ($data = $ilDB->fetchAssoc($result))
513  {
514  $this->columns->addCategory($data["title"], $data["other"], $data["neutral"], null, ($data['scale']) ? $data['scale'] : ($data['sequence'] + 1));
515  }
516  }
517 
518  $result = $ilDB->queryF("SELECT * FROM svy_qst_matrixrows WHERE question_fi = %s ORDER BY sequence",
519  array('integer'),
520  array($id)
521  );
522  while ($row = $ilDB->fetchAssoc($result))
523  {
524  $this->addRow($row["title"], $row['other'], $row['label']);
525  }
526  }
528  }
529 
536  function isComplete()
537  {
538  if (
539  strlen($this->getTitle()) &&
540  strlen($this->getAuthor()) &&
541  strlen($this->getQuestiontext()) &&
542  $this->getColumnCount() &&
543  $this->getRowCount()
544  )
545  {
546  return 1;
547  }
548  else
549  {
550  return 0;
551  }
552  }
553 
559  function saveToDb($original_id = NULL, $withanswers = true)
560  {
561  global $ilDB;
562 
563  $affectedRows = parent::saveToDb($original_id);
564 
565  if ($affectedRows == 1)
566  {
567  $affectedRows = $ilDB->manipulateF("DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
568  array('integer'),
569  array($this->getId())
570  );
571  $affectedRows = $ilDB->manipulateF("INSERT INTO " . $this->getAdditionalTableName() . " (
572  question_fi, subtype, column_separators, row_separators, neutral_column_separator,column_placeholders,
573  legend, singleline_row_caption, repeat_column_header, column_header_position, random_rows,
574  column_order, column_images, row_images, bipolar_adjective1, bipolar_adjective2, layout, tstamp)
575  VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
576  array(
577  'integer', 'integer', 'text', 'text', 'text', 'integer', 'text', 'text', 'text',
578  'text', 'text', 'text', 'text', 'text', 'text', 'text', 'text', 'integer'
579  ),
580  array(
581  $this->getId(),
582  $this->getSubtype(),
583  $this->getColumnSeparators(),
584  $this->getRowSeparators(),
585  $this->getNeutralColumnSeparator(),
586  $this->getColumnPlaceholders(),
587  $this->getLegend(),
588  $this->getSingleLineRowCaption(),
589  $this->getRepeatColumnHeader(),
590  $this->getColumnHeaderPosition(),
591  $this->getRandomRows(),
592  $this->getColumnOrder(),
593  $this->getColumnImages(),
594  $this->getRowImages(),
595  $this->getBipolarAdjective(0),
596  $this->getBipolarAdjective(1),
597  serialize($this->getLayout()),
598  time()
599  )
600  );
601 
602  // saving material uris in the database
603  $this->saveMaterial();
604 
605  $this->saveColumnsToDb();
606  $this->saveRowsToDb();
607  }
608  }
609 
610  function saveBipolarAdjectives($adjective1, $adjective2)
611  {
612  global $ilDB;
613 
614  $affectedRows = $ilDB->manipulateF("UPDATE " . $this->getAdditionalTableName() . " SET bipolar_adjective1 = %s, bipolar_adjective2 = %s WHERE question_fi = %s",
615  array('text', 'text', 'integer'),
616  array((strlen($adjective1)) ? $adjective1 : NULL, (strlen($adjective2)) ? $adjective2 : NULL, $this->getId())
617  );
618  }
619 
628  function saveColumnToDb($columntext, $neutral = 0)
629  {
630  global $ilUser, $ilDB;
631 
632  $result = $ilDB->queryF("SELECT title, category_id FROM svy_category WHERE title = %s AND neutral = %s AND owner_fi = %s",
633  array('text', 'text', 'integer'),
634  array($columntext, $neutral, $ilUser->getId())
635  );
636  $insert = FALSE;
637  $returnvalue = "";
638  if ($result->numRows())
639  {
640  $insert = TRUE;
641  while ($row = $ilDB->fetchAssoc($result))
642  {
643  if (strcmp($row["title"], $columntext) == 0)
644  {
645  $returnvalue = $row["category_id"];
646  $insert = FALSE;
647  }
648  }
649  }
650  else
651  {
652  $insert = TRUE;
653  }
654  if ($insert)
655  {
656  $next_id = $ilDB->nextId('svy_category');
657  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_category (category_id, title, defaultvalue, owner_fi, neutral, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
658  array('integer', 'text', 'text', 'integer', 'text', 'integer'),
659  array($next_id, $columntext, 0, $ilUser->getId(), $neutral, time())
660  );
661  $returnvalue = $next_id;
662  }
663  return $returnvalue;
664  }
665 
666  function saveColumnsToDb($original_id = "")
667  {
668  global $ilDB;
669 
670  // save columns
671  $question_id = $this->getId();
672  if (strlen($original_id))
673  {
674  $question_id = $original_id;
675  }
676 
677  // delete existing column relations
678  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_variable WHERE question_fi = %s",
679  array('integer'),
680  array($question_id)
681  );
682  // create new column relations
683  for ($i = 0; $i < $this->getColumnCount(); $i++)
684  {
685  $cat = $this->getColumn($i);
686  $column_id = $this->saveColumnToDb($cat->title, $cat->neutral);
687  $next_id = $ilDB->nextId('svy_variable');
688  $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)",
689  array('integer','integer','integer','float','integer','integer', 'integer','integer'),
690  array($next_id, $column_id, $question_id, ($i + 1), $cat->other, $i, ($cat->scale > 0) ? $cat->scale : null, time())
691  );
692  }
693  $this->saveCompletionStatus($original_id);
694  }
695 
696  function saveRowsToDb($original_id = "")
697  {
698  global $ilDB;
699 
700  // save rows
701  $question_id = $this->getId();
702  if (strlen($original_id))
703  {
704  $question_id = $original_id;
705  }
706 
707  // delete existing rows
708  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qst_matrixrows WHERE question_fi = %s",
709  array('integer'),
710  array($question_id)
711  );
712  // create new rows
713  for ($i = 0; $i < $this->getRowCount(); $i++)
714  {
715  $row = $this->getRow($i);
716  $next_id = $ilDB->nextId('svy_qst_matrixrows');
717  $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)",
718  array('integer','text','text','integer','integer','integer'),
719  array($next_id, $row->title, $row->label, ($row->other) ? 1 : 0, $i, $question_id)
720  );
721  }
722  $this->saveCompletionStatus($original_id);
723  }
724 
731  function toXML($a_include_header = TRUE, $obligatory_state = "")
732  {
733  include_once("./Services/Xml/classes/class.ilXmlWriter.php");
734  $a_xml_writer = new ilXmlWriter;
735  $a_xml_writer->xmlHeader();
736  $this->insertXML($a_xml_writer, $a_include_header, $obligatory_state);
737  $xml = $a_xml_writer->xmlDumpMem(FALSE);
738  if (!$a_include_header)
739  {
740  $pos = strpos($xml, "?>");
741  $xml = substr($xml, $pos + 2);
742  }
743  return $xml;
744  }
745 
754  function insertXML(&$a_xml_writer, $a_include_header = TRUE, $obligatory_state = "")
755  {
756  $attrs = array(
757  "id" => $this->getId(),
758  "title" => $this->getTitle(),
759  "type" => $this->getQuestiontype(),
760  "subtype" => $this->getSubtype(),
761  "obligatory" => $this->getObligatory()
762  );
763  $a_xml_writer->xmlStartTag("question", $attrs);
764 
765  $a_xml_writer->xmlElement("description", NULL, $this->getDescription());
766  $a_xml_writer->xmlElement("author", NULL, $this->getAuthor());
767  $a_xml_writer->xmlStartTag("questiontext");
768  $this->addMaterialTag($a_xml_writer, $this->getQuestiontext());
769  $a_xml_writer->xmlEndTag("questiontext");
770 
771  $a_xml_writer->xmlStartTag("matrix");
772  $a_xml_writer->xmlStartTag("matrixrows");
773  for ($i = 0; $i < $this->getRowCount(); $i++)
774  {
775  $attrs = array(
776  "id" => $i
777  );
778  if (strlen($this->getRow($i)->label))
779  {
780  $attrs['label'] = $this->getRow($i)->label;
781  }
782  if ($this->getRow($i)->other)
783  {
784  $attrs['other'] = 1;
785  }
786  $a_xml_writer->xmlStartTag("matrixrow", $attrs);
787  $this->addMaterialTag($a_xml_writer, $this->getRow($i)->title);
788  $a_xml_writer->xmlEndTag("matrixrow");
789  }
790  $a_xml_writer->xmlEndTag("matrixrows");
791 
792  $a_xml_writer->xmlStartTag("responses");
793  if (strlen($this->getBipolarAdjective(0)) && (strlen($this->getBipolarAdjective(1))))
794  {
795  $a_xml_writer->xmlStartTag("bipolar_adjectives");
796  $attribs = array(
797  "label" => "0"
798  );
799  $a_xml_writer->xmlElement("adjective", $attribs, $this->getBipolarAdjective(0));
800  $attribs = array(
801  "label" => "1"
802  );
803  $a_xml_writer->xmlElement("adjective", $attribs, $this->getBipolarAdjective(1));
804  $a_xml_writer->xmlEndTag("bipolar_adjectives");
805  }
806  for ($i = 0; $i < $this->getColumnCount(); $i++)
807  {
808  $attrs = array(
809  "id" => $i
810  );
811  if ($this->getColumn($i)->neutral)
812  {
813  $attrs['label'] = 'neutral';
814  }
815  switch ($this->getSubtype())
816  {
817  case 0:
818  $a_xml_writer->xmlStartTag("response_single", $attrs);
819  break;
820  case 1:
821  $a_xml_writer->xmlStartTag("response_multiple", $attrs);
822  break;
823  }
824  $this->addMaterialTag($a_xml_writer, $this->getColumn($i)->title);
825  switch ($this->getSubtype())
826  {
827  case 0:
828  $a_xml_writer->xmlEndTag("response_single");
829  break;
830  case 1:
831  $a_xml_writer->xmlEndTag("response_multiple");
832  break;
833  }
834  }
835 
836  $a_xml_writer->xmlEndTag("responses");
837  $a_xml_writer->xmlEndTag("matrix");
838 
839  if (count($this->material))
840  {
841  if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $this->material["internal_link"], $matches))
842  {
843  $attrs = array(
844  "label" => $this->material["title"]
845  );
846  $a_xml_writer->xmlStartTag("material", $attrs);
847  $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
848  if (strcmp($matches[1], "") != 0)
849  {
850  $intlink = $this->material["internal_link"];
851  }
852  $a_xml_writer->xmlElement("mattext", NULL, $intlink);
853  $a_xml_writer->xmlEndTag("material");
854  }
855  }
856 
857  $a_xml_writer->xmlStartTag("metadata");
858  $a_xml_writer->xmlStartTag("metadatafield");
859  $a_xml_writer->xmlElement("fieldlabel", NULL, "column_separators");
860  $a_xml_writer->xmlElement("fieldentry", NULL, $this->getColumnSeparators());
861  $a_xml_writer->xmlEndTag("metadatafield");
862 
863  $a_xml_writer->xmlStartTag("metadatafield");
864  $a_xml_writer->xmlElement("fieldlabel", NULL, "row_separators");
865  $a_xml_writer->xmlElement("fieldentry", NULL, $this->getRowSeparators());
866  $a_xml_writer->xmlEndTag("metadatafield");
867 
868  $a_xml_writer->xmlStartTag("metadatafield");
869  $a_xml_writer->xmlElement("fieldlabel", NULL, "neutral_column_separator");
870  $a_xml_writer->xmlElement("fieldentry", NULL, $this->getNeutralColumnSeparator());
871  $a_xml_writer->xmlEndTag("metadatafield");
872 
873  $a_xml_writer->xmlStartTag("metadatafield");
874  $a_xml_writer->xmlElement("fieldlabel", NULL, "layout");
875  $a_xml_writer->xmlElement("fieldentry", NULL, serialize($this->getLayout()));
876  $a_xml_writer->xmlEndTag("metadatafield");
877 
878  $a_xml_writer->xmlEndTag("metadata");
879 
880  $a_xml_writer->xmlEndTag("question");
881  }
882 
883  function syncWithOriginal()
884  {
885  if ($this->getOriginalId())
886  {
888  $this->saveColumnsToDb($this->getOriginalId());
889  $this->saveRowsToDb($this->getOriginalId());
890  }
891  }
892 
893 
901  function addStandardNumbers($lower_limit, $upper_limit)
902  {
903  for ($i = $lower_limit; $i <= $upper_limit; $i++)
904  {
905  $this->columns->addCategory($i);
906  }
907  }
908 
916  function savePhrase($title)
917  {
918  global $ilUser;
919  global $ilDB;
920 
921  $next_id = $ilDB->nextId('svy_phrase');
922  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_phrase (phrase_id, title, defaultvalue, owner_fi, tstamp) VALUES (%s, %s, %s, %s, %s)",
923  array('integer','text','text','integer','integer'),
924  array($next_id, $title, 1, $ilUser->getId(), time())
925  );
926  $phrase_id = $next_id;
927 
928  $counter = 1;
929  foreach ($_SESSION['save_phrase_data'] as $data)
930  {
931  $next_id = $ilDB->nextId('svy_category');
932  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_category (category_id, title, defaultvalue, owner_fi, tstamp, neutral) VALUES (%s, %s, %s, %s, %s, %s)",
933  array('integer','text','text','integer','integer','text'),
934  array($next_id, $data['answer'], 1, $ilUser->getId(), time(), $data['neutral'])
935  );
936  $category_id = $next_id;
937  $next_id = $ilDB->nextId('svy_phrase_cat');
938  $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)",
939  array('integer', 'integer', 'integer','integer', 'integer', 'integer'),
940  array($next_id, $phrase_id, $category_id, $counter, ($data['other']) ? 1 : 0, $data['scale'])
941  );
942  $counter++;
943  }
944  }
945 
952  function getQuestionType()
953  {
954  return "SurveyMatrixQuestion";
955  }
956 
964  {
965  return "svy_qst_matrix";
966  }
967 
974  function &getWorkingDataFromUserInput($post_data)
975  {
976  $data = array();
977  foreach ($post_data as $key => $value)
978  {
979  switch ($this->getSubtype())
980  {
981  case 0:
982  if (preg_match("/matrix_" . $this->getId() . "_(\d+)/", $key, $matches))
983  {
984  if (is_array($value))
985  {
986  foreach ($value as $val)
987  {
988  array_push($data, array("value" => $val, "rowvalue" => $matches[1], "textanswer" => $post_data['matrix_other_' . $this->getId() . '_' . $matches[1]]));
989  }
990  }
991  else
992  {
993  array_push($data, array("value" => $value, "rowvalue" => $matches[1], "textanswer" => $post_data['matrix_other_' . $this->getId() . '_' . $matches[1]]));
994  }
995  }
996  break;
997  case 1:
998  if (preg_match("/matrix_" . $this->getId() . "_(\d+)/", $key, $matches))
999  {
1000  if (is_array($value))
1001  {
1002  foreach ($value as $val)
1003  {
1004  array_push($data, array("value" => $val, "rowvalue" => $matches[1], "textanswer" => $post_data['matrix_other_' . $this->getId() . '_' . $matches[1]]));
1005  }
1006  }
1007  else
1008  {
1009  array_push($data, array("value" => $value, "rowvalue" => $matches[1], "textanswer" => $post_data['matrix_other_' . $this->getId() . '_' . $matches[1]]));
1010  }
1011  }
1012  break;
1013  }
1014  }
1015  return $data;
1016  }
1017 
1027  function checkUserInput($post_data, $survey_id)
1028  {
1029  if (!$this->getObligatory($survey_id)) return "";
1030  switch ($this->getSubtype())
1031  {
1032  case 0:
1033  $counter = 0;
1034  foreach ($post_data as $key => $value)
1035  {
1036  if (preg_match("/matrix_" . $this->getId() . "_(\d+)/", $key, $matches))
1037  {
1038  if (array_key_exists('matrix_other_' . $this->getId() . "_" . $matches[1], $post_data) && strlen($post_data['matrix_other_' . $this->getId() . "_" . $matches[1]]) == 0)
1039  {
1040  return $this->lng->txt("question_mr_no_other_answer");
1041  }
1042  $counter++;
1043  }
1044  }
1045  if ($counter != $this->getRowCount()) return $this->lng->txt("matrix_question_radio_button_not_checked");
1046  break;
1047  case 1:
1048  $counter = 0;
1049  foreach ($post_data as $key => $value)
1050  {
1051  if (preg_match("/matrix_" . $this->getId() . "_(\d+)/", $key, $matches))
1052  {
1053  if (array_key_exists('matrix_other_' . $this->getId() . "_" . $matches[1], $post_data) && strlen($post_data['matrix_other_' . $this->getId() . "_" . $matches[1]]) == 0)
1054  {
1055  return $this->lng->txt("question_mr_no_other_answer");
1056  }
1057  $counter++;
1058  if ((!is_array($value)) || (count($value) < 1))
1059  {
1060  return $this->lng->txt("matrix_question_checkbox_not_checked");
1061  }
1062  }
1063  }
1064  if ($counter != $this->getRowCount()) return $this->lng->txt("matrix_question_checkbox_not_checked");
1065  break;
1066  }
1067  return "";
1068  }
1069 
1075  public function saveRandomData($active_id)
1076  {
1077  global $ilDB;
1078  $columncount = $this->getColumnCount();
1079  for ($row = 0; $row < $this->getRowCount(); $row++)
1080  {
1081  if ($this->getSubType() == 1)
1082  {
1083  // multiple responses
1084  for ($i = 0; $i < $columncount; $i++)
1085  {
1086  if (rand(0,1))
1087  {
1088  $next_id = $ilDB->nextId('svy_answer');
1089  $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)",
1090  array('integer','integer','integer','float','text','integer','integer'),
1091  array($next_id, $this->getId(), $active_id, $i, NULL, $row, time())
1092  );
1093  }
1094  }
1095  }
1096  else
1097  {
1098  // single responses
1099  $category = rand(0, $columncount-1);
1100  $next_id = $ilDB->nextId('svy_answer');
1101  $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)",
1102  array('integer','integer','integer','float','text','integer','integer'),
1103  array($next_id, $this->getId(), $active_id, $category, NULL, $row, time())
1104  );
1105  }
1106  }
1107  }
1108 
1109  function saveUserInput($post_data, $active_id, $a_return = false)
1110  {
1111  global $ilDB;
1112 
1113  if($a_return)
1114  {
1115  $return_data = array();
1116  }
1117  switch ($this->getSubtype())
1118  {
1119  case 0:
1120  foreach ($post_data as $key => $value)
1121  {
1122  if (preg_match("/matrix_" . $this->getId() . "_(\d+)/", $key, $matches))
1123  {
1124  $other_value = (array_key_exists('matrix_other_' . $this->getId() . '_' . $matches[1], $post_data)) ? ($post_data['matrix_other_' . $this->getId() . '_' . $matches[1]]) : null;
1125  if(!$a_return)
1126  {
1127  $next_id = $ilDB->nextId('svy_answer');
1128  $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)",
1129  array('integer','integer','integer','float','text','integer','integer'),
1130  array($next_id, $this->getId(), $active_id, $value, $other_value, $matches[1], time())
1131  );
1132  }
1133  else
1134  {
1135  $return_data[] = array("value"=>$value,
1136  "textanswer"=>$other_value,
1137  "rowvalue"=>$matches[1]);
1138  }
1139  }
1140  }
1141  break;
1142  case 1:
1143  foreach ($post_data as $key => $value)
1144  {
1145  if (preg_match("/matrix_" . $this->getId() . "_(\d+)/", $key, $matches))
1146  {
1147  $other_value = (array_key_exists('matrix_other_' . $this->getId() . '_' . $matches[1], $post_data)) ? ($post_data['matrix_other_' . $this->getId() . '_' . $matches[1]]) : null;
1148  foreach ($value as $checked)
1149  {
1150  if (strlen($checked))
1151  {
1152  if(!$a_return)
1153  {
1154  $next_id = $ilDB->nextId('svy_answer');
1155  $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)",
1156  array('integer','integer','integer','float','text','integer','integer'),
1157  array($next_id, $this->getId(), $active_id, $checked, $other_value, $matches[1], time())
1158  );
1159  }
1160  else
1161  {
1162  $return_data[] = array("value"=>$checked,
1163  "textanswer"=>$other_value,
1164  "rowvalue"=>$matches[1]);
1165  }
1166  }
1167  }
1168  }
1169  }
1170  break;
1171  }
1172  if($a_return)
1173  {
1174  return $return_data;
1175  }
1176  }
1177 
1184  function deleteAdditionalTableData($question_id)
1185  {
1186  parent::deleteAdditionalTableData($question_id);
1187 
1188  global $ilDB;
1189  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qst_matrixrows WHERE question_fi = %s",
1190  array('integer'),
1191  array($question_id)
1192  );
1193  }
1194 
1203  {
1204  global $ilDB;
1205 
1206  $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",
1207  array('integer', 'integer'),
1208  array($this->getId(), $survey_id)
1209  );
1210  $found = array();
1211  while ($row = $ilDB->fetchAssoc($result))
1212  {
1213  $found[$row["active_fi"].$row["question_fi"]] = 1;
1214  }
1215  return count($found);
1216  }
1217 
1226  function &getCumulatedResultsForRow($rowindex, $survey_id, $nr_of_users)
1227  {
1228  global $ilDB;
1229 
1230  $question_id = $this->getId();
1231 
1232  $result_array = array();
1233  $cumulated = array();
1234 
1235  $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",
1236  array('integer', 'integer', 'integer'),
1237  array($question_id, $survey_id, $rowindex)
1238  );
1239 
1240  switch ($this->getSubtype())
1241  {
1242  case 0:
1243  case 1:
1244  while ($row = $ilDB->fetchAssoc($result))
1245  {
1246  $cumulated[$row["value"]]++;
1247 
1248  // add text value to result array
1249  if ($row["textanswer"])
1250  {
1251  $result_array["textanswers"][$row["value"]][] = $row["textanswer"];
1252  }
1253  }
1254  // sort textanswers by value
1255  if (is_array($result_array["textanswers"]))
1256  {
1257  ksort($result_array["textanswers"], SORT_NUMERIC);
1258  }
1259  asort($cumulated, SORT_NUMERIC);
1260  end($cumulated);
1261  break;
1262  }
1263  $numrows = $result->numRows();
1264  $result_array["USERS_ANSWERED"] = $this->getNrOfUsersAnswered($survey_id);
1265  $result_array["USERS_SKIPPED"] = $nr_of_users - $this->getNrOfUsersAnswered($survey_id);
1266 
1267  $prefix = "";
1268  if (strcmp(key($cumulated), "") != 0)
1269  {
1270  $prefix = (key($cumulated)+1) . " - ";
1271  }
1272  $cat = $this->getColumnForScale(key($cumulated)+1);
1273  $result_array["MODE"] = $prefix . $cat->title;
1274  $result_array["MODE_VALUE"] = key($cumulated)+1;
1275  $result_array["MODE_NR_OF_SELECTIONS"] = $cumulated[key($cumulated)];
1276  for ($key = 0; $key < $this->getColumnCount(); $key++)
1277  {
1278  $cat = $this->getColumn($key);
1279  $scale = $cat->scale-1;
1280 
1281  $percentage = 0;
1282  if ($numrows > 0)
1283  {
1284  $percentage = (float)((int)$cumulated[$scale]/$numrows);
1285  }
1286 
1287  $result_array["variables"][$key] = array("title" => $cat->title, "selected" => (int)$cumulated[$scale], "percentage" => $percentage);
1288  }
1289  ksort($cumulated, SORT_NUMERIC);
1290  $median = array();
1291  $total = 0;
1292  foreach ($cumulated as $value => $key)
1293  {
1294  $total += $key;
1295  for ($i = 0; $i < $key; $i++)
1296  {
1297  array_push($median, $value+1);
1298  }
1299  }
1300  if ($total > 0)
1301  {
1302  if (($total % 2) == 0)
1303  {
1304  $median_value = 0.5 * ($median[($total/2)-1] + $median[($total/2)]);
1305  if (round($median_value) != $median_value)
1306  {
1307  $cat = $this->getColumnForScale((int)floor($median_value));
1308  $cat2 = $this->getColumnForScale((int)ceil($median_value));
1309  $median_value = $median_value . "<br />" . "(" . $this->lng->txt("median_between") . " " . (floor($median_value)) . "-" . $cat->title . " " . $this->lng->txt("and") . " " . (ceil($median_value)) . "-" . $cat2->title . ")";
1310  }
1311  }
1312  else
1313  {
1314  $median_value = $median[(($total+1)/2)-1];
1315  }
1316  }
1317  else
1318  {
1319  $median_value = "";
1320  }
1321  $result_array["ARITHMETIC_MEAN"] = "";
1322  $result_array["MEDIAN"] = $median_value;
1323  $result_array["QUESTION_TYPE"] = "SurveyMatrixQuestion";
1324  $result_array["ROW"] = $this->getRow($rowindex)->title;
1325  return $result_array;
1326  }
1327 
1335  function &getCumulatedResults($survey_id, $nr_of_users)
1336  {
1337  global $ilDB;
1338 
1339  $question_id = $this->getId();
1340 
1341  $result_array = array();
1342  $cumulated = array();
1343 
1344  $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",
1345  array('integer', 'integer'),
1346  array($question_id, $survey_id)
1347  );
1348 
1349  switch ($this->getSubtype())
1350  {
1351  case 0:
1352  case 1:
1353  while ($row = $ilDB->fetchAssoc($result))
1354  {
1355  $cumulated[$row["value"]]++;
1356  }
1357  asort($cumulated, SORT_NUMERIC);
1358  end($cumulated);
1359  break;
1360  }
1361  $numrows = $result->numRows();
1362  $result_array["USERS_ANSWERED"] = $this->getNrOfUsersAnswered($survey_id);
1363  $result_array["USERS_SKIPPED"] = $nr_of_users - $this->getNrOfUsersAnswered($survey_id);
1364 
1365  $prefix = "";
1366  if (strcmp(key($cumulated), "") != 0)
1367  {
1368  $prefix = (key($cumulated)+1) . " - ";
1369  }
1370  $cat = $this->getColumnForScale(key($cumulated)+1);
1371  $result_array["MODE"] = $prefix . $cat->title;
1372  $result_array["MODE_VALUE"] = key($cumulated)+1;
1373  $result_array["MODE_NR_OF_SELECTIONS"] = $cumulated[key($cumulated)];
1374  for ($key = 0; $key < $this->getColumnCount(); $key++)
1375  {
1376  $cat = $this->getColumn($key);
1377  $scale = $cat->scale-1;
1378 
1379  $percentage = 0;
1380  if ($numrows > 0)
1381  {
1382  $percentage = (float)((int)$cumulated[$scale]/$numrows);
1383  }
1384 
1385  $result_array["variables"][$key] = array("title" => $cat->title, "selected" => (int)$cumulated[$scale], "percentage" => $percentage);
1386  }
1387  ksort($cumulated, SORT_NUMERIC);
1388  $median = array();
1389  $total = 0;
1390  foreach ($cumulated as $value => $key)
1391  {
1392  $total += $key;
1393  for ($i = 0; $i < $key; $i++)
1394  {
1395  array_push($median, $value+1);
1396  }
1397  }
1398  if ($total > 0)
1399  {
1400  if (($total % 2) == 0)
1401  {
1402  $median_value = 0.5 * ($median[($total/2)-1] + $median[($total/2)]);
1403  if (round($median_value) != $median_value)
1404  {
1405  $cat = $this->getColumnForScale((int)floor($median_value));
1406  $cat2 = $this->getColumnForScale((int)ceil($median_value));
1407  $median_value = $median_value . "<br />" . "(" . $this->lng->txt("median_between") . " " . (floor($median_value)) . "-" . $cat->title . " " . $this->lng->txt("and") . " " . (ceil($median_value)) . "-" . $cat2->title . ")";
1408  }
1409  }
1410  else
1411  {
1412  $median_value = $median[(($total+1)/2)-1];
1413  }
1414  }
1415  else
1416  {
1417  $median_value = "";
1418  }
1419  $result_array["ARITHMETIC_MEAN"] = "";
1420  $result_array["MEDIAN"] = $median_value;
1421  $result_array["QUESTION_TYPE"] = "SurveyMatrixQuestion";
1422 
1423  $cumulated_results = array();
1424  $cumulated_results["TOTAL"] = $result_array;
1425  for ($i = 0; $i < $this->getRowCount(); $i++)
1426  {
1427  $rowresult =& $this->getCumulatedResultsForRow($i, $survey_id, $nr_of_users);
1428  $cumulated_results[$i] = $rowresult;
1429  }
1430  return $cumulated_results;
1431  }
1432 
1444  function setExportCumulatedXLS(&$worksheet, &$format_title, &$format_bold, &$eval_data, $row, $export_label)
1445  {
1446  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
1447  $column = 0;
1448  switch ($export_label)
1449  {
1450  case 'label_only':
1451  $worksheet->writeString($row, $column, ilExcelUtils::_convert_text($this->label));
1452  break;
1453  case 'title_only':
1454  $worksheet->writeString($row, $column, ilExcelUtils::_convert_text($this->getTitle()));
1455  break;
1456  default:
1457  $worksheet->writeString($row, $column, ilExcelUtils::_convert_text($this->getTitle()));
1458  $column++;
1459  $worksheet->writeString($row, $column, ilExcelUtils::_convert_text($this->label));
1460  break;
1461  }
1462  $column++;
1463  $worksheet->writeString($row, $column, ilExcelUtils::_convert_text(strip_tags($this->getQuestiontext()))); // #12942
1464  $column++;
1465  $worksheet->writeString($row, $column, ilExcelUtils::_convert_text($this->lng->txt($eval_data["TOTAL"]["QUESTION_TYPE"])));
1466  $column++;
1467  $worksheet->write($row, $column, $eval_data["TOTAL"]["USERS_ANSWERED"]);
1468  $column++;
1469  $worksheet->write($row, $column, $eval_data["TOTAL"]["USERS_SKIPPED"]);
1470  $column++;
1471  $worksheet->write($row, $column, ilExcelUtils::_convert_text($eval_data["TOTAL"]["MODE_VALUE"]));
1472  $column++;
1473  $worksheet->write($row, $column, ilExcelUtils::_convert_text($eval_data["TOTAL"]["MODE"]));
1474  $column++;
1475  $worksheet->write($row, $column, $eval_data["TOTAL"]["MODE_NR_OF_SELECTIONS"]);
1476  $column++;
1477  $worksheet->write($row, $column, ilExcelUtils::_convert_text(str_replace("<br />", " ", $eval_data["TOTAL"]["MEDIAN"])));
1478  $column++;
1479  $worksheet->write($row, $column, $eval_data["TOTAL"]["ARITHMETIC_MEAN"]);
1480  $row++;
1481  $add = 0;
1482  switch ($export_label)
1483  {
1484  case 'label_only':
1485  case 'title_only':
1486  break;
1487  default:
1488  $add = 1;
1489  break;
1490  }
1491  foreach ($eval_data as $evalkey => $evalvalue)
1492  {
1493  if (is_numeric($evalkey))
1494  {
1495  $worksheet->writeString($row, 1+$add, ilExcelUtils::_convert_text($evalvalue["ROW"]));
1496  $worksheet->write($row, 3+$add, $evalvalue["USERS_ANSWERED"]);
1497  $worksheet->write($row, 4+$add, $evalvalue["USERS_SKIPPED"]);
1498  $worksheet->write($row, 5+$add, ilExcelUtils::_convert_text($evalvalue["MODE_VALUE"]));
1499  $worksheet->write($row, 6+$add, ilExcelUtils::_convert_text($evalvalue["MODE"]));
1500  $worksheet->write($row, 7+$add, $evalvalue["MODE_NR_OF_SELECTIONS"]);
1501  $worksheet->write($row, 8+$add, ilExcelUtils::_convert_text(str_replace("<br />", " ", $evalvalue["MEDIAN"])));
1502  $worksheet->write($row, 9+$add, $evalvalue["ARITHMETIC_MEAN"]);
1503  $row++;
1504  }
1505  }
1506  return $row;
1507  }
1508 
1520  function &setExportCumulatedCVS(&$eval_data, $export_label)
1521  {
1522  $result = array();
1523  foreach ($eval_data as $evalkey => $evalvalue)
1524  {
1525  $csvrow = array();
1526  if (is_numeric($evalkey))
1527  {
1528  array_push($csvrow, "");
1529  array_push($csvrow, $evalvalue["ROW"]);
1530  array_push($csvrow, "");
1531  }
1532  else
1533  {
1534  switch ($export_label)
1535  {
1536  case 'label_only':
1537  array_push($csvrow, $this->label);
1538  break;
1539  case 'title_only':
1540  array_push($csvrow, $this->getTitle());
1541  break;
1542  default:
1543  array_push($csvrow, $this->getTitle());
1544  array_push($csvrow, $this->label);
1545  break;
1546  }
1547  array_push($csvrow, strip_tags($this->getQuestiontext())); // #12942
1548  array_push($csvrow, $this->lng->txt($evalvalue["QUESTION_TYPE"]));
1549  }
1550  array_push($csvrow, $evalvalue["USERS_ANSWERED"]);
1551  array_push($csvrow, $evalvalue["USERS_SKIPPED"]);
1552  array_push($csvrow, $evalvalue["MODE"]);
1553  array_push($csvrow, $evalvalue["MODE_NR_OF_SELECTIONS"]);
1554  array_push($csvrow, $evalvalue["MEDIAN"]);
1555  array_push($csvrow, $evalvalue["ARITHMETIC_MEAN"]);
1556  array_push($result, $csvrow);
1557  }
1558  return $result;
1559  }
1560 
1570  function setExportDetailsXLS(&$workbook, &$format_title, &$format_bold, &$eval_data, $export_label)
1571  {
1572  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
1573  $worksheet =& $workbook->addWorksheet();
1574  $rowcounter = 0;
1575  switch ($export_label)
1576  {
1577  case 'label_only':
1578  $worksheet->writeString(0, 0, ilExcelUtils::_convert_text($this->lng->txt("label")), $format_bold);
1579  $worksheet->writeString(0, 1, ilExcelUtils::_convert_text($this->label));
1580  break;
1581  case 'title_only':
1582  $worksheet->writeString(0, 0, ilExcelUtils::_convert_text($this->lng->txt("title")), $format_bold);
1583  $worksheet->writeString(0, 1, ilExcelUtils::_convert_text($this->getTitle()));
1584  break;
1585  default:
1586  $worksheet->writeString(0, 0, ilExcelUtils::_convert_text($this->lng->txt("title")), $format_bold);
1587  $worksheet->writeString(0, 1, ilExcelUtils::_convert_text($this->getTitle()));
1588  $rowcounter++;
1589  $worksheet->writeString($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("label")), $format_bold);
1590  $worksheet->writeString($rowcounter, 1, ilExcelUtils::_convert_text($this->label));
1591  break;
1592  }
1593  $rowcounter++;
1594  $worksheet->writeString($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("question")), $format_bold);
1595  $worksheet->writeString($rowcounter, 1, ilExcelUtils::_convert_text($this->getQuestiontext()));
1596  $rowcounter++;
1597  $worksheet->writeString($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("question_type")), $format_bold);
1598  $worksheet->writeString($rowcounter, 1, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())));
1599  $rowcounter++;
1600  $worksheet->writeString($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("users_answered")), $format_bold);
1601  $worksheet->write($rowcounter, 1, $eval_data["TOTAL"]["USERS_ANSWERED"]);
1602  $rowcounter++;
1603  $worksheet->writeString($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("users_skipped")), $format_bold);
1604  $worksheet->write($rowcounter, 1, $eval_data["TOTAL"]["USERS_SKIPPED"]);
1605  $rowcounter++;
1606 
1607  preg_match("/(.*?)\s+-\s+(.*)/", $eval_data["TOTAL"]["MODE"], $matches);
1608  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode")), $format_bold);
1609  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($matches[1]));
1610  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode_text")), $format_bold);
1611  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($matches[2]));
1612  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode_nr_of_selections")), $format_bold);
1613  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($eval_data["TOTAL"]["MODE_NR_OF_SELECTIONS"]));
1614  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("median")), $format_bold);
1615  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text(str_replace("<br />", " ", $eval_data["TOTAL"]["MEDIAN"])));
1616  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("categories")), $format_bold);
1617  $worksheet->write($rowcounter, 1, ilExcelUtils::_convert_text($this->lng->txt("title")), $format_title);
1618  $worksheet->write($rowcounter, 2, ilExcelUtils::_convert_text($this->lng->txt("value")), $format_title);
1619  $worksheet->write($rowcounter, 3, ilExcelUtils::_convert_text($this->lng->txt("category_nr_selected")), $format_title);
1620  $worksheet->write($rowcounter++, 4, ilExcelUtils::_convert_text($this->lng->txt("percentage_of_selections")), $format_title);
1621 
1622  foreach ($eval_data["TOTAL"]["variables"] as $key => $value)
1623  {
1624  $worksheet->write($rowcounter, 1, ilExcelUtils::_convert_text($value["title"]));
1625  $worksheet->write($rowcounter, 2, $key+1);
1626  $worksheet->write($rowcounter, 3, ilExcelUtils::_convert_text($value["selected"]));
1627  $worksheet->write($rowcounter++, 4, ilExcelUtils::_convert_text($value["percentage"]), $format_percent);
1628  }
1629 
1630  foreach ($eval_data as $evalkey => $evalvalue)
1631  {
1632  if (is_numeric($evalkey))
1633  {
1634  $worksheet->writeString($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("row")), $format_bold);
1635  $worksheet->writeString($rowcounter, 1, ilExcelUtils::_convert_text($evalvalue["ROW"]));
1636  $worksheet->writeString($rowcounter + 1, 0, ilExcelUtils::_convert_text($this->lng->txt("users_answered")), $format_bold);
1637  $worksheet->write($rowcounter + 1, 1, $evalvalue["USERS_ANSWERED"]);
1638  $worksheet->writeString($rowcounter + 2, 0, ilExcelUtils::_convert_text($this->lng->txt("users_skipped")), $format_bold);
1639  $worksheet->write($rowcounter + 2, 1, $evalvalue["USERS_SKIPPED"]);
1640  $rowcounter = $rowcounter + 3;
1641 
1642  preg_match("/(.*?)\s+-\s+(.*)/", $evalvalue["MODE"], $matches);
1643  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode")), $format_bold);
1644  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($matches[1]));
1645  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode_text")), $format_bold);
1646  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($matches[2]));
1647  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode_nr_of_selections")), $format_bold);
1648  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($evalvalue["MODE_NR_OF_SELECTIONS"]));
1649  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("median")), $format_bold);
1650  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text(str_replace("<br />", " ", $evalvalue["MEDIAN"])));
1651  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("categories")), $format_bold);
1652  $worksheet->write($rowcounter, 1, ilExcelUtils::_convert_text($this->lng->txt("title")), $format_title);
1653  $worksheet->write($rowcounter, 2, ilExcelUtils::_convert_text($this->lng->txt("value")), $format_title);
1654  $worksheet->write($rowcounter, 3, ilExcelUtils::_convert_text($this->lng->txt("category_nr_selected")), $format_title);
1655  $worksheet->write($rowcounter++, 4, ilExcelUtils::_convert_text($this->lng->txt("percentage_of_selections")), $format_title);
1656 
1657  foreach ($evalvalue["variables"] as $key => $value)
1658  {
1659  $worksheet->write($rowcounter, 1, ilExcelUtils::_convert_text($value["title"]));
1660  $worksheet->write($rowcounter, 2, $key+1);
1661  $worksheet->write($rowcounter, 3, ilExcelUtils::_convert_text($value["selected"]));
1662  $worksheet->write($rowcounter++, 4, ilExcelUtils::_convert_text($value["percentage"]), $format_percent);
1663  }
1664 
1665  // add text answers to detailed results
1666  if (is_array($evalvalue["textanswers"]))
1667  {
1668  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("freetext_answers")), $format_bold);
1669  $worksheet->write($rowcounter, 1, ilExcelUtils::_convert_text($this->lng->txt("title")), $format_title);
1670  $worksheet->write($rowcounter++, 2, ilExcelUtils::_convert_text($this->lng->txt("answer")), $format_title);
1671 
1672  foreach ($evalvalue["textanswers"] as $key => $answers)
1673  {
1674  $title = $evalvalue["variables"][$key]["title"];
1675  foreach ($answers as $answer)
1676  {
1677  $worksheet->write($rowcounter, 1, ilExcelUtils::_convert_text($title));
1678  $worksheet->write($rowcounter++, 2, ilExcelUtils::_convert_text($answer));
1679  }
1680  }
1681  }
1682  }
1683  }
1684  // out compressed 2D-Matrix
1685  $format_center =& $workbook->addFormat();
1686  $format_center->setColor('black');
1687  $format_center->setAlign('center');
1688 
1689  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("overview")), $format_bold);
1690  // title row with variables
1691  $rowcounter++;
1692  $counter = 0;
1693  $worksheet->write($rowcounter, $counter, "", $format_title);
1694  foreach ($eval_data["TOTAL"]["variables"] as $variable)
1695  {
1696  $worksheet->write($rowcounter, 1+$counter, ilExcelUtils::_convert_text($variable["title"]), $format_title);
1697  $counter++;
1698  }
1699  $rowcounter++;
1700  // rows with variable values
1701  foreach ($eval_data as $index => $data)
1702  {
1703  if (is_numeric($index))
1704  {
1705  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($data["ROW"]), $format_title);
1706  $counter = 1;
1707  foreach ($data["variables"] as $vardata)
1708  {
1709  $worksheet->write($rowcounter, $counter, $vardata["selected"], $format_center);
1710  $counter++;
1711  }
1712  $rowcounter++;
1713  }
1714  }
1715  }
1716 
1723  function addUserSpecificResultsExportTitles(&$a_array, $a_use_label = false, $a_substitute = true)
1724  {
1725  parent::addUserSpecificResultsExportTitles($a_array, $a_use_label, $a_substitute);
1726 
1727  for ($i = 0; $i < $this->getRowCount(); $i++)
1728  {
1729  // create row title according label, add 'other column'
1730  $row = $this->getRow($i);
1731 
1732  if(!$a_use_label)
1733  {
1734  $title = $row->title;
1735  }
1736  else
1737  {
1738  if($a_substitute)
1739  {
1740  $title = $row->label ? $row->label : $row->title;
1741  }
1742  else
1743  {
1744  $title = $row->label;
1745  }
1746  }
1747  array_push($a_array, $title);
1748 
1749  if ($row->other)
1750  {
1751  if(!$a_use_label || $a_substitute)
1752  {
1753  array_push($a_array, $title. ' - '. $this->lng->txt('other'));
1754  }
1755  else
1756  {
1757  array_push($a_array, "");
1758  }
1759  }
1760 
1761  switch ($this->getSubtype())
1762  {
1763  case 0:
1764  break;
1765  case 1:
1766  for ($index = 0; $index < $this->getColumnCount(); $index++)
1767  {
1768  $col = $this->getColumn($index);
1769  if(!$a_use_label || $a_substitute)
1770  {
1771  array_push($a_array, ($index+1) . " - " . $col->title);
1772  }
1773  else
1774  {
1775  array_push($a_array, "");
1776  }
1777  }
1778  break;
1779  }
1780  }
1781  }
1782 
1790  function addUserSpecificResultsData(&$a_array, &$resultset)
1791  {
1792  if (count($resultset["answers"][$this->getId()]))
1793  {
1794  array_push($a_array, "");
1795  switch ($this->getSubtype())
1796  {
1797  case 0:
1798  for ($i = 0; $i < $this->getRowCount(); $i++)
1799  {
1800  // add textanswer column for single choice mode
1801  $row = $this->getRow($i);
1802  $textanswer = "";
1803  $checked = FALSE;
1804  foreach ($resultset["answers"][$this->getId()] as $result)
1805  {
1806  if ($result["rowvalue"] == $i)
1807  {
1808  $checked = TRUE;
1809  array_push($a_array, $result["value"] + 1);
1810 
1811  if ($result["textanswer"])
1812  {
1813  $textanswer = $result["textanswer"];
1814  }
1815  }
1816  }
1817  if (!$checked)
1818  {
1819  array_push($a_array, $this->lng->txt("skipped"));
1820  }
1821  if ($row->other)
1822  {
1823  array_push($a_array, $textanswer);
1824  }
1825  }
1826  break;
1827  case 1:
1828  for ($i = 0; $i < $this->getRowCount(); $i++)
1829  {
1830  // add textanswer column for multiple choice mode
1831  $row = $this->getRow($i);
1832  $textanswer = "";
1833  $checked = FALSE;
1834  $checked_values = array();
1835  foreach ($resultset["answers"][$this->getId()] as $result)
1836  {
1837  if ($result["rowvalue"] == $i)
1838  {
1839  $checked = TRUE;
1840  array_push($checked_values, $result["value"] + 1);
1841 
1842  if ($result["textanswer"])
1843  {
1844  $textanswer = $result["textanswer"];
1845  }
1846  }
1847  }
1848  if (!$checked)
1849  {
1850  array_push($a_array, $this->lng->txt("skipped"));
1851  }
1852  else
1853  {
1854  array_push($a_array, "");
1855  }
1856  if ($row->other)
1857  {
1858  array_push($a_array, $textanswer);
1859  }
1860  for ($index = 0; $index < $this->getColumnCount(); $index++)
1861  {
1862  if (!$checked)
1863  {
1864  array_push($a_array, "");
1865  }
1866  else
1867  {
1868  $cat = $this->getColumn($index);
1869  $scale = $cat->scale;
1870  if (in_array($scale, $checked_values))
1871  {
1872  array_push($a_array, $scale);
1873  }
1874  else
1875  {
1876  array_push($a_array, 0);
1877  }
1878  }
1879  }
1880  }
1881  break;
1882  }
1883  }
1884  else
1885  {
1886  array_push($a_array, $this->lng->txt("skipped"));
1887  for ($i = 0; $i < $this->getRowCount(); $i++)
1888  {
1889  array_push($a_array, "");
1890 
1891  // add empty "other" column if not answered
1892  $row = $this->getRow($i);
1893  if ($row->other)
1894  {
1895  array_push($a_array, "");
1896  }
1897 
1898  switch ($this->getSubtype())
1899  {
1900  case 0:
1901  break;
1902  case 1:
1903  for ($index = 0; $index < $this->getColumnCount(); $index++)
1904  {
1905  array_push($a_array, "");
1906  }
1907  break;
1908  }
1909  }
1910  }
1911  }
1912 
1921  {
1922  global $ilDB;
1923 
1924  $answers = array();
1925 
1926  $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",
1927  array('integer','integer'),
1928  array($survey_id, $this->getId())
1929  );
1930  $results = array();
1931  while ($row = $ilDB->fetchAssoc($result))
1932  {
1933  $column = $this->getColumnForScale($row["value"]+1);
1934  if (!is_array($answers[$row["active_fi"]])) $answers[$row["active_fi"]] = array();
1935  $rowobj = $this->getRow($row["rowvalue"]);
1936  array_push($answers[$row["active_fi"]], $rowobj->title . (($rowobj->other) ? (" " . $row["textanswer"]) : "") . ": " . ($row["value"] + 1) . " - " . $column->title);
1937  }
1938  foreach ($answers as $key => $value)
1939  {
1940  $answers[$key] = implode("<br />", $value);
1941  }
1942  return $answers;
1943  }
1944 
1951  function getSubtype()
1952  {
1953  return $this->subtype;
1954  }
1955 
1962  function setSubtype($a_subtype = 0)
1963  {
1964  switch ($a_subtype)
1965  {
1966  case 1:
1967  case 2:
1968  case 3:
1969  case 4:
1970  case 5:
1971  case 6:
1972  $this->subtype = $a_subtype;
1973  break;
1974  case 0:
1975  default:
1976  $this->subtype = 0;
1977  break;
1978  }
1979  }
1980 
1987  function setColumnSeparators($enable = 0)
1988  {
1989  switch ($enable)
1990  {
1991  case 1:
1992  $this->columnSeparators = 1;
1993  break;
1994  case 0:
1995  default:
1996  $this->columnSeparators = 0;
1997  break;
1998  }
1999  }
2000 
2008  {
2009  return ($this->columnSeparators) ? 1 : 0;
2010  }
2011 
2018  function setRowSeparators($enable = 0)
2019  {
2020  switch ($enable)
2021  {
2022  case 1:
2023  $this->rowSeparators = 1;
2024  break;
2025  case 0:
2026  default:
2027  $this->rowSeparators = 0;
2028  break;
2029  }
2030  }
2031 
2038  function getRowSeparators()
2039  {
2040  return ($this->rowSeparators) ? 1 : 0;
2041  }
2042 
2049  function setNeutralColumnSeparator($enable = 0)
2050  {
2051  switch ($enable)
2052  {
2053  case 1:
2054  $this->neutralColumnSeparator = 1;
2055  break;
2056  case 0:
2057  default:
2058  $this->neutralColumnSeparator = 0;
2059  break;
2060  }
2061  }
2062 
2070  {
2071  return ($this->neutralColumnSeparator) ? 1 : 0;
2072  }
2073 
2082  function importAdditionalMetadata($a_meta)
2083  {
2084  foreach ($a_meta as $key => $value)
2085  {
2086  switch ($value["label"])
2087  {
2088  case "column_separators":
2089  $this->setColumnSeparators($value["entry"]);
2090  break;
2091  case "row_separators":
2092  $this->setRowSeparators($value["entry"]);
2093  break;
2094  case "layout":
2095  $this->setLayout($value["entry"]);
2096  break;
2097  case "neutral_column_separator":
2098  $this->setNeutralColumnSeparator($value["entry"]);
2099  break;
2100  }
2101  }
2102  }
2103 
2110  function importAdjectives($a_data)
2111  {
2112  $i = 0;
2113  foreach ($a_data as $adjective)
2114  {
2115  if (is_numeric($adjective["label"]))
2116  {
2117  $this->setBipolarAdjective($adjective["label"], $adjective["text"]);
2118  }
2119  else
2120  {
2121  $this->setBipolarAdjective($i, $adjective["text"]);
2122  }
2123  $i++;
2124  }
2125  }
2126 
2133  function importMatrix($a_data)
2134  {
2135  foreach ($a_data as $row)
2136  {
2137  $this->addRow($row['title'], $row['other'], $row['label']);
2138  }
2139  }
2140 
2147  function importResponses($a_data)
2148  {
2149  foreach ($a_data as $id => $data)
2150  {
2151  $column = "";
2152  foreach ($data["material"] as $material)
2153  {
2154  $column .= $material["text"];
2155  }
2156  $this->columns->addCategory($column, null, (strcmp($data["label"], "neutral") == 0) ? true : false);
2157  }
2158  }
2159 
2167  {
2168  return FALSE;
2169  }
2170 
2179  {
2180  return $value;
2181  }
2182 
2189  public function getPreconditionSelectValue($default = "", $title, $variable)
2190  {
2191  include_once "./Services/Form/classes/class.ilSelectInputGUI.php";
2192  $step3 = new ilSelectInputGUI($title, $variable);
2193  $options = $this->getPreconditionOptions();
2194  $step3->setOptions($options);
2195  $step3->setValue($default);
2196  return $step3;
2197  }
2198 
2208  function saveLayout($percent_row, $percent_columns, $percent_bipolar_adjective1 = "", $percent_bipolar_adjective2 = "", $percent_neutral)
2209  {
2210  global $ilDB;
2211 
2212  $layout = array(
2213  "percent_row" => $percent_row,
2214  "percent_columns" => $percent_columns,
2215  "percent_bipolar_adjective1" => $percent_bipolar_adjective1,
2216  "percent_bipolar_adjective2" => $percent_bipolar_adjective2,
2217  "percent_neutral" => $percent_neutral
2218  );
2219  $affectedRows = $ilDB->manipulateF("UPDATE " . $this->getAdditionalTableName() . " SET layout = %s WHERE question_fi = %s",
2220  array('text', 'integer'),
2221  array(serialize($layout), $this->getId())
2222  );
2223  }
2224 
2225  function getLayout()
2226  {
2227  if (!is_array($this->layout) || count($this->layout) == 0)
2228  {
2229  if ($this->hasBipolarAdjectives() && $this->hasNeutralColumn())
2230  {
2231  $this->layout = array(
2232  "percent_row" => 30,
2233  "percent_columns" => 40,
2234  "percent_bipolar_adjective1" => 10,
2235  "percent_bipolar_adjective2" => 10,
2236  "percent_neutral" => 10
2237  );
2238  }
2239  elseif ($this->hasBipolarAdjectives())
2240  {
2241  $this->layout = array(
2242  "percent_row" => 30,
2243  "percent_columns" => 50,
2244  "percent_bipolar_adjective1" => 10,
2245  "percent_bipolar_adjective2" => 10,
2246  "percent_neutral" => 0
2247  );
2248  }
2249  elseif ($this->hasNeutralColumn())
2250  {
2251  $this->layout = array(
2252  "percent_row" => 30,
2253  "percent_columns" => 50,
2254  "percent_bipolar_adjective1" => 0,
2255  "percent_bipolar_adjective2" => 0,
2256  "percent_neutral" => 20
2257  );
2258  }
2259  else
2260  {
2261  $this->layout = array(
2262  "percent_row" => 30,
2263  "percent_columns" => 70,
2264  "percent_bipolar_adjective1" => 0,
2265  "percent_bipolar_adjective2" => 0,
2266  "percent_neutral" => 0
2267  );
2268  }
2269  }
2270  return $this->layout;
2271  }
2272 
2273  function setLayout($layout)
2274  {
2275  if (is_array($layout))
2276  {
2277  $this->layout = $layout;
2278  }
2279  else
2280  {
2281  $this->layout = unserialize($layout);
2282  }
2283  }
2284 
2291  {
2292  if ((strlen($this->getBipolarAdjective(0))) && (strlen($this->getBipolarAdjective(1))))
2293  {
2294  return TRUE;
2295  }
2296  else
2297  {
2298  return FALSE;
2299  }
2300  }
2301 
2307  function hasNeutralColumn()
2308  {
2309  for ($i = 0; $i < $this->getColumnCount(); $i++)
2310  {
2311  $column = $this->getColumn($i);
2312  if ($column->neutral && strlen($column->title)) return true;
2313  }
2314  return FALSE;
2315  }
2316 
2322  function setColumnPlaceholders($a_value = 0)
2323  {
2324  $this->columnPlaceholders = ($a_value) ? 1 : 0;
2325  }
2326 
2333  {
2334  return ($this->columnPlaceholders) ? 1 : 0;
2335  }
2336 
2342  function setLegend($a_value = 0)
2343  {
2344  $this->legend = ($a_value) ? 1 : 0;
2345  }
2346 
2352  function getLegend()
2353  {
2354  return ($this->legend) ? 1 : 0;
2355  }
2356 
2357  function setSingleLineRowCaption($a_value = 0)
2358  {
2359  $this->singleLineRowCaption = ($a_value) ? 1 : 0;
2360  }
2361 
2363  {
2364  return ($this->singleLineRowCaption) ? 1 : 0;
2365  }
2366 
2367  function setRepeatColumnHeader($a_value = 0)
2368  {
2369  $this->repeatColumnHeader = ($a_value) ? 1 : 0;
2370  }
2371 
2373  {
2374  return ($this->repeatColumnHeader) ? 1 : 0;
2375  }
2376 
2377  function setColumnHeaderPosition($a_value)
2378  {
2379  $this->columnHeaderPosition = $a_value;
2380  }
2381 
2383  {
2384  return ($this->columnHeaderPosition) ? $this->columnHeaderPosition : 0;
2385  }
2386 
2387  function setRandomRows($a_value = 0)
2388  {
2389  $this->randomRows = ($a_value) ? 1 : 0;
2390  }
2391 
2392  function getRandomRows()
2393  {
2394  return ($this->randomRows) ? 1 : 0;
2395  }
2396 
2397  function setColumnOrder($a_value)
2398  {
2399  $this->columnOrder = $a_value;
2400  }
2401 
2402  function getColumnOrder()
2403  {
2404  return ($this->columnOrder) ? $this->columnOrder : 0;
2405  }
2406 
2407  function setColumnImages($a_value = 0)
2408  {
2409  $this->columnImages = ($a_value) ? 1 : 0;
2410  }
2411 
2412  function getColumnImages()
2413  {
2414  return ($this->columnImages) ? 1 : 0;
2415  }
2416 
2417  function setRowImages($a_value = 0)
2418  {
2419  $this->rowImages = ($a_value) ? 1 : 0;
2420  }
2421 
2422  function getRowImages()
2423  {
2424  return ($this->rowImages) ? 1 : 0;
2425  }
2426 
2427  public function getRows()
2428  {
2429  return $this->rows;
2430  }
2431 
2437  public function getCumulatedResultData($survey_id, $counter)
2438  {
2440  $questiontext = preg_replace("/<[^>]+?>/ims", "", $this->getQuestiontext());
2441 
2442  include_once "./Services/Utilities/classes/class.ilStr.php";
2443  $maxlen = 75;
2444  if (strlen($questiontext) > $maxlen + 3)
2445  {
2446  $questiontext = ilStr::substr($questiontext, 0, $maxlen) . "...";
2447  }
2448 
2449  $result = array();
2450  $row = array(
2451  'counter' => $counter,
2452  'title' => $this->getTitle(),
2453  'question' => $questiontext,
2454  'users_answered' => $cumulated['TOTAL']['USERS_ANSWERED'],
2455  'users_skipped' => $cumulated['TOTAL']['USERS_SKIPPED'],
2456  'question_type' => $this->lng->txt($cumulated['TOTAL']['QUESTION_TYPE']),
2457  'mode' => $cumulated['TOTAL']['MODE'],
2458  'mode_nr_of_selections' => $cumulated['TOTAL']['MODE_NR_OF_SELECTIONS'],
2459  'median' => $cumulated['TOTAL']['MEDIAN'],
2460  'arithmetic_mean' => $cumulated['TOTAL']['ARITHMETIC_MEAN']
2461  );
2462  array_push($result, $row);
2463  $maxlen -= 3;
2464  foreach ($cumulated as $key => $value)
2465  {
2466  if (is_numeric($key))
2467  {
2468  if (strlen($value['ROW']) > $maxlen + 3)
2469  {
2470  $value['ROW'] = ilStr::substr($value['ROW'], 0, $maxlen) . "...";
2471  }
2472 
2473  $row = array(
2474  'title' => '',
2475  'question' => ($key+1) . ". " . $value['ROW'],
2476  'users_answered' => $value['USERS_ANSWERED'],
2477  'users_skipped' => $value['USERS_SKIPPED'],
2478  'question_type' => '',
2479  'mode' => $value["MODE"],
2480  'mode_nr_of_selections' => $value["MODE_NR_OF_SELECTIONS"],
2481  'median' => $value["MEDIAN"],
2482  'arithmetic_mean' => $value["ARITHMETIC_MEAN"]
2483  );
2484  array_push($result, $row);
2485  }
2486  }
2487  return $result;
2488  }
2489 }
2490 ?>