ILIAS  Release_4_2_x_branch Revision 61807
 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($this->getQuestiontext()));
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, $this->getQuestiontext());
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_export_label = "")
1724  {
1725  parent::addUserSpecificResultsExportTitles($a_array, $a_export_label);
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  switch ($a_export_label)
1732  {
1733  case "label_only":
1734  $title = $row->label ? $row->label : $row->title;
1735  break;
1736 
1737  case "title_only":
1738  $title = $row->title;
1739  break;
1740 
1741  default:
1742  $title = $row->label ? $row->title." - ".$row->label : $row->title;
1743  break;
1744  }
1745  array_push($a_array, $title);
1746 
1747  if ($row->other)
1748  {
1749  array_push($a_array, $title. ' - '. $this->lng->txt('other'));
1750  }
1751 
1752  switch ($this->getSubtype())
1753  {
1754  case 0:
1755  break;
1756  case 1:
1757  for ($index = 0; $index < $this->getColumnCount(); $index++)
1758  {
1759  $col = $this->getColumn($index);
1760  array_push($a_array, ($index+1) . " - " . $col->title);
1761  }
1762  break;
1763  }
1764  }
1765  }
1766 
1774  function addUserSpecificResultsData(&$a_array, &$resultset)
1775  {
1776  if (count($resultset["answers"][$this->getId()]))
1777  {
1778  array_push($a_array, "");
1779  switch ($this->getSubtype())
1780  {
1781  case 0:
1782  for ($i = 0; $i < $this->getRowCount(); $i++)
1783  {
1784  // add textanswer column for single choice mode
1785  $row = $this->getRow($i);
1786  $textanswer = "";
1787  $checked = FALSE;
1788  foreach ($resultset["answers"][$this->getId()] as $result)
1789  {
1790  if ($result["rowvalue"] == $i)
1791  {
1792  $checked = TRUE;
1793  array_push($a_array, $result["value"] + 1);
1794 
1795  if ($result["textanswer"])
1796  {
1797  $textanswer = $result["textanswer"];
1798  }
1799  }
1800  }
1801  if (!$checked)
1802  {
1803  array_push($a_array, $this->lng->txt("skipped"));
1804  }
1805  if ($row->other)
1806  {
1807  array_push($a_array, $textanswer);
1808  }
1809  }
1810  break;
1811  case 1:
1812  for ($i = 0; $i < $this->getRowCount(); $i++)
1813  {
1814  // add textanswer column for multiple choice mode
1815  $row = $this->getRow($i);
1816  $textanswer = "";
1817  $checked = FALSE;
1818  $checked_values = array();
1819  foreach ($resultset["answers"][$this->getId()] as $result)
1820  {
1821  if ($result["rowvalue"] == $i)
1822  {
1823  $checked = TRUE;
1824  array_push($checked_values, $result["value"] + 1);
1825 
1826  if ($result["textanswer"])
1827  {
1828  $textanswer = $result["textanswer"];
1829  }
1830  }
1831  }
1832  if (!$checked)
1833  {
1834  array_push($a_array, $this->lng->txt("skipped"));
1835  }
1836  else
1837  {
1838  array_push($a_array, "");
1839  }
1840  if ($row->other)
1841  {
1842  array_push($a_array, $textanswer);
1843  }
1844  for ($index = 0; $index < $this->getColumnCount(); $index++)
1845  {
1846  if (!$checked)
1847  {
1848  array_push($a_array, "");
1849  }
1850  else
1851  {
1852  $cat = $this->getColumn($index);
1853  $scale = $cat->scale;
1854  if (in_array($scale, $checked_values))
1855  {
1856  array_push($a_array, $scale);
1857  }
1858  else
1859  {
1860  array_push($a_array, 0);
1861  }
1862  }
1863  }
1864  }
1865  break;
1866  }
1867  }
1868  else
1869  {
1870  array_push($a_array, $this->lng->txt("skipped"));
1871  for ($i = 0; $i < $this->getRowCount(); $i++)
1872  {
1873  array_push($a_array, "");
1874 
1875  // add empty "other" column if not answered
1876  $row = $this->getRow($i);
1877  if ($row->other)
1878  {
1879  array_push($a_array, "");
1880  }
1881 
1882  switch ($this->getSubtype())
1883  {
1884  case 0:
1885  break;
1886  case 1:
1887  for ($index = 0; $index < $this->getColumnCount(); $index++)
1888  {
1889  array_push($a_array, "");
1890  }
1891  break;
1892  }
1893  }
1894  }
1895  }
1896 
1905  {
1906  global $ilDB;
1907 
1908  $answers = array();
1909 
1910  $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",
1911  array('integer','integer'),
1912  array($survey_id, $this->getId())
1913  );
1914  $results = array();
1915 
1916  while ($row = $ilDB->fetchAssoc($result))
1917  {
1918  $column = $this->getColumnForScale($row["value"]+1);
1919  if (!is_array($answers[$row["active_fi"]])) $answers[$row["active_fi"]] = array();
1920  $rowobj = $this->getRow($row["rowvalue"]);
1921  array_push($answers[$row["active_fi"]], $rowobj->title . (($rowobj->other) ? (" " . $row["textanswer"]) : "") . ": " . ($row["value"] + 1) . " - " . $column->title);
1922  }
1923  foreach ($answers as $key => $value)
1924  {
1925  $answers[$key] = implode("<br />", $value);
1926  }
1927  return $answers;
1928  }
1929 
1936  function getSubtype()
1937  {
1938  return $this->subtype;
1939  }
1940 
1947  function setSubtype($a_subtype = 0)
1948  {
1949  switch ($a_subtype)
1950  {
1951  case 1:
1952  case 2:
1953  case 3:
1954  case 4:
1955  case 5:
1956  case 6:
1957  $this->subtype = $a_subtype;
1958  break;
1959  case 0:
1960  default:
1961  $this->subtype = 0;
1962  break;
1963  }
1964  }
1965 
1972  function setColumnSeparators($enable = 0)
1973  {
1974  switch ($enable)
1975  {
1976  case 1:
1977  $this->columnSeparators = 1;
1978  break;
1979  case 0:
1980  default:
1981  $this->columnSeparators = 0;
1982  break;
1983  }
1984  }
1985 
1993  {
1994  return ($this->columnSeparators) ? 1 : 0;
1995  }
1996 
2003  function setRowSeparators($enable = 0)
2004  {
2005  switch ($enable)
2006  {
2007  case 1:
2008  $this->rowSeparators = 1;
2009  break;
2010  case 0:
2011  default:
2012  $this->rowSeparators = 0;
2013  break;
2014  }
2015  }
2016 
2023  function getRowSeparators()
2024  {
2025  return ($this->rowSeparators) ? 1 : 0;
2026  }
2027 
2034  function setNeutralColumnSeparator($enable = 0)
2035  {
2036  switch ($enable)
2037  {
2038  case 1:
2039  $this->neutralColumnSeparator = 1;
2040  break;
2041  case 0:
2042  default:
2043  $this->neutralColumnSeparator = 0;
2044  break;
2045  }
2046  }
2047 
2055  {
2056  return ($this->neutralColumnSeparator) ? 1 : 0;
2057  }
2058 
2067  function importAdditionalMetadata($a_meta)
2068  {
2069  foreach ($a_meta as $key => $value)
2070  {
2071  switch ($value["label"])
2072  {
2073  case "column_separators":
2074  $this->setColumnSeparators($value["entry"]);
2075  break;
2076  case "row_separators":
2077  $this->setRowSeparators($value["entry"]);
2078  break;
2079  case "layout":
2080  $this->setLayout($value["entry"]);
2081  break;
2082  case "neutral_column_separator":
2083  $this->setNeutralColumnSeparator($value["entry"]);
2084  break;
2085  }
2086  }
2087  }
2088 
2095  function importAdjectives($a_data)
2096  {
2097  $i = 0;
2098  foreach ($a_data as $adjective)
2099  {
2100  if (is_numeric($adjective["label"]))
2101  {
2102  $this->setBipolarAdjective($adjective["label"], $adjective["text"]);
2103  }
2104  else
2105  {
2106  $this->setBipolarAdjective($i, $adjective["text"]);
2107  }
2108  $i++;
2109  }
2110  }
2111 
2118  function importMatrix($a_data)
2119  {
2120  foreach ($a_data as $row)
2121  {
2122  $this->addRow($row['title'], $row['other'], $row['label']);
2123  }
2124  }
2125 
2132  function importResponses($a_data)
2133  {
2134  foreach ($a_data as $id => $data)
2135  {
2136  $column = "";
2137  foreach ($data["material"] as $material)
2138  {
2139  $column .= $material["text"];
2140  }
2141  $this->columns->addCategory($column, null, (strcmp($data["label"], "neutral") == 0) ? true : false);
2142  }
2143  }
2144 
2152  {
2153  return FALSE;
2154  }
2155 
2164  {
2165  return $value;
2166  }
2167 
2174  public function getPreconditionSelectValue($default = "", $title, $variable)
2175  {
2176  include_once "./Services/Form/classes/class.ilSelectInputGUI.php";
2177  $step3 = new ilSelectInputGUI($title, $variable);
2178  $options = $this->getPreconditionOptions();
2179  $step3->setOptions($options);
2180  $step3->setValue($default);
2181  return $step3;
2182  }
2183 
2193  function saveLayout($percent_row, $percent_columns, $percent_bipolar_adjective1 = "", $percent_bipolar_adjective2 = "", $percent_neutral)
2194  {
2195  global $ilDB;
2196 
2197  $layout = array(
2198  "percent_row" => $percent_row,
2199  "percent_columns" => $percent_columns,
2200  "percent_bipolar_adjective1" => $percent_bipolar_adjective1,
2201  "percent_bipolar_adjective2" => $percent_bipolar_adjective2,
2202  "percent_neutral" => $percent_neutral
2203  );
2204  $affectedRows = $ilDB->manipulateF("UPDATE " . $this->getAdditionalTableName() . " SET layout = %s WHERE question_fi = %s",
2205  array('text', 'integer'),
2206  array(serialize($layout), $this->getId())
2207  );
2208  }
2209 
2210  function getLayout()
2211  {
2212  if (!is_array($this->layout) || count($this->layout) == 0)
2213  {
2214  if ($this->hasBipolarAdjectives() && $this->hasNeutralColumn())
2215  {
2216  $this->layout = array(
2217  "percent_row" => 30,
2218  "percent_columns" => 40,
2219  "percent_bipolar_adjective1" => 10,
2220  "percent_bipolar_adjective2" => 10,
2221  "percent_neutral" => 10
2222  );
2223  }
2224  elseif ($this->hasBipolarAdjectives())
2225  {
2226  $this->layout = array(
2227  "percent_row" => 30,
2228  "percent_columns" => 50,
2229  "percent_bipolar_adjective1" => 10,
2230  "percent_bipolar_adjective2" => 10,
2231  "percent_neutral" => 0
2232  );
2233  }
2234  elseif ($this->hasNeutralColumn())
2235  {
2236  $this->layout = array(
2237  "percent_row" => 30,
2238  "percent_columns" => 50,
2239  "percent_bipolar_adjective1" => 0,
2240  "percent_bipolar_adjective2" => 0,
2241  "percent_neutral" => 20
2242  );
2243  }
2244  else
2245  {
2246  $this->layout = array(
2247  "percent_row" => 30,
2248  "percent_columns" => 70,
2249  "percent_bipolar_adjective1" => 0,
2250  "percent_bipolar_adjective2" => 0,
2251  "percent_neutral" => 0
2252  );
2253  }
2254  }
2255  return $this->layout;
2256  }
2257 
2258  function setLayout($layout)
2259  {
2260  if (is_array($layout))
2261  {
2262  $this->layout = $layout;
2263  }
2264  else
2265  {
2266  $this->layout = unserialize($layout);
2267  }
2268  }
2269 
2276  {
2277  if ((strlen($this->getBipolarAdjective(0))) && (strlen($this->getBipolarAdjective(1))))
2278  {
2279  return TRUE;
2280  }
2281  else
2282  {
2283  return FALSE;
2284  }
2285  }
2286 
2292  function hasNeutralColumn()
2293  {
2294  foreach ($this->columns as $column)
2295  {
2296  if ($column->neutral && strlen($column->title)) return true;
2297  }
2298  return FALSE;
2299  }
2300 
2306  function setColumnPlaceholders($a_value = 0)
2307  {
2308  $this->columnPlaceholders = ($a_value) ? 1 : 0;
2309  }
2310 
2317  {
2318  return ($this->columnPlaceholders) ? 1 : 0;
2319  }
2320 
2326  function setLegend($a_value = 0)
2327  {
2328  $this->legend = ($a_value) ? 1 : 0;
2329  }
2330 
2336  function getLegend()
2337  {
2338  return ($this->legend) ? 1 : 0;
2339  }
2340 
2341  function setSingleLineRowCaption($a_value = 0)
2342  {
2343  $this->singleLineRowCaption = ($a_value) ? 1 : 0;
2344  }
2345 
2347  {
2348  return ($this->singleLineRowCaption) ? 1 : 0;
2349  }
2350 
2351  function setRepeatColumnHeader($a_value = 0)
2352  {
2353  $this->repeatColumnHeader = ($a_value) ? 1 : 0;
2354  }
2355 
2357  {
2358  return ($this->repeatColumnHeader) ? 1 : 0;
2359  }
2360 
2361  function setColumnHeaderPosition($a_value)
2362  {
2363  $this->columnHeaderPosition = $a_value;
2364  }
2365 
2367  {
2368  return ($this->columnHeaderPosition) ? $this->columnHeaderPosition : 0;
2369  }
2370 
2371  function setRandomRows($a_value = 0)
2372  {
2373  $this->randomRows = ($a_value) ? 1 : 0;
2374  }
2375 
2376  function getRandomRows()
2377  {
2378  return ($this->randomRows) ? 1 : 0;
2379  }
2380 
2381  function setColumnOrder($a_value)
2382  {
2383  $this->columnOrder = $a_value;
2384  }
2385 
2386  function getColumnOrder()
2387  {
2388  return ($this->columnOrder) ? $this->columnOrder : 0;
2389  }
2390 
2391  function setColumnImages($a_value = 0)
2392  {
2393  $this->columnImages = ($a_value) ? 1 : 0;
2394  }
2395 
2396  function getColumnImages()
2397  {
2398  return ($this->columnImages) ? 1 : 0;
2399  }
2400 
2401  function setRowImages($a_value = 0)
2402  {
2403  $this->rowImages = ($a_value) ? 1 : 0;
2404  }
2405 
2406  function getRowImages()
2407  {
2408  return ($this->rowImages) ? 1 : 0;
2409  }
2410 
2411  public function getRows()
2412  {
2413  return $this->rows;
2414  }
2415 
2421  public function getCumulatedResultData($survey_id, $counter)
2422  {
2424  $questiontext = preg_replace("/<[^>]+?>/ims", "", $this->getQuestiontext());
2425 
2426  include_once "./Services/Utilities/classes/class.ilStr.php";
2427  $maxlen = 75;
2428  if (strlen($questiontext) > $maxlen + 3)
2429  {
2430  $questiontext = ilStr::substr($questiontext, 0, $maxlen) . "...";
2431  }
2432 
2433  $result = array();
2434  $row = array(
2435  'counter' => $counter,
2436  'title' => $this->getTitle(),
2437  'question' => $questiontext,
2438  'users_answered' => $cumulated['TOTAL']['USERS_ANSWERED'],
2439  'users_skipped' => $cumulated['TOTAL']['USERS_SKIPPED'],
2440  'question_type' => $this->lng->txt($cumulated['TOTAL']['QUESTION_TYPE']),
2441  'mode' => $cumulated['TOTAL']['MODE'],
2442  'mode_nr_of_selections' => $cumulated['TOTAL']['MODE_NR_OF_SELECTIONS'],
2443  'median' => $cumulated['TOTAL']['MEDIAN'],
2444  'arithmetic_mean' => $cumulated['TOTAL']['ARITHMETIC_MEAN']
2445  );
2446  array_push($result, $row);
2447  $maxlen -= 3;
2448  foreach ($cumulated as $key => $value)
2449  {
2450  if (is_numeric($key))
2451  {
2452  if (strlen($value['ROW']) > $maxlen + 3)
2453  {
2454  $value['ROW'] = ilStr::substr($value['ROW'], 0, $maxlen) . "...";
2455  }
2456 
2457  $row = array(
2458  'title' => '',
2459  'question' => ($key+1) . ". " . $value['ROW'],
2460  'users_answered' => $value['USERS_ANSWERED'],
2461  'users_skipped' => $value['USERS_SKIPPED'],
2462  'question_type' => '',
2463  'mode' => $value["MODE"],
2464  'mode_nr_of_selections' => $value["MODE_NR_OF_SELECTIONS"],
2465  'median' => $value["MEDIAN"],
2466  'arithmetic_mean' => $value["ARITHMETIC_MEAN"]
2467  );
2468  array_push($result, $row);
2469  }
2470  }
2471  return $result;
2472  }
2473 }
2474 ?>