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