00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 include_once "./survey/classes/class.SurveyQuestion.php";
00025 include_once "./survey/classes/inc.SurveyConstants.php";
00026
00027 define("SUBTYPE_MCSR", 1);
00028 define("SUBTYPE_MCMR", 2);
00029
00041 class SurveyNominalQuestion extends SurveyQuestion
00042 {
00050 var $subtype;
00051
00059 var $categories;
00060
00072 function SurveyNominalQuestion(
00073 $title = "",
00074 $description = "",
00075 $author = "",
00076 $questiontext = "",
00077 $owner = -1,
00078 $subtype = SUBTYPE_MCSR,
00079 $orientation = 0
00080 )
00081
00082 {
00083 $this->SurveyQuestion($title, $description, $author, $questiontext, $owner);
00084 $this->subtype = $subtype;
00085 $this->orientation = $orientation;
00086 include_once "./survey/classes/class.SurveyCategories.php";
00087 $this->categories = new SurveyCategories();
00088 }
00089
00099 function setSubtype($subtype = SUBTYPE_MCSR)
00100 {
00101 $this->subtype = $subtype;
00102 }
00103
00113 function getSubtype()
00114 {
00115 return $this->subtype;
00116 }
00117
00127 function _getQuestionDataArray($id)
00128 {
00129 global $ilDB;
00130
00131 $query = sprintf("SELECT survey_question.*, survey_question_nominal.* FROM survey_question, survey_question_nominal WHERE survey_question.question_id = %s AND survey_question.question_id = survey_question_nominal.question_fi",
00132 $ilDB->quote($id)
00133 );
00134 $result = $ilDB->query($query);
00135 if ($result->numRows() == 1)
00136 {
00137 return $result->fetchRow(DB_FETCHMODE_ASSOC);
00138 }
00139 else
00140 {
00141 return array();
00142 }
00143 }
00144
00153 function loadFromDb($id)
00154 {
00155 global $ilDB;
00156 $query = sprintf("SELECT survey_question.*, survey_question_nominal.* FROM survey_question, survey_question_nominal WHERE survey_question.question_id = %s AND survey_question.question_id = survey_question_nominal.question_fi",
00157 $ilDB->quote($id)
00158 );
00159 $result = $ilDB->query($query);
00160 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00161 {
00162 if ($result->numRows() == 1)
00163 {
00164 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00165 $this->id = $data->question_id;
00166 $this->title = $data->title;
00167 $this->description = $data->description;
00168 $this->obj_id = $data->obj_fi;
00169 $this->author = $data->author;
00170 $this->subtype = $data->subtype;
00171 $this->orientation = $data->orientation;
00172 $this->obligatory = $data->obligatory;
00173 $this->owner = $data->owner_fi;
00174 include_once("./Services/RTE/classes/class.ilRTE.php");
00175 $this->questiontext = ilRTE::_replaceMediaObjectImageSrc($data->questiontext, 1);
00176 $this->complete = $data->complete;
00177 $this->original_id = $data->original_id;
00178 }
00179
00180 $this->loadMaterialFromDb($id);
00181
00182 $this->categories->flushCategories();
00183 $query = sprintf("SELECT survey_variable.*, survey_category.title FROM survey_variable, survey_category WHERE survey_variable.question_fi = %s AND survey_variable.category_fi = survey_category.category_id ORDER BY sequence ASC",
00184 $ilDB->quote($id)
00185 );
00186 $result = $ilDB->query($query);
00187 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00188 {
00189 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00190 {
00191 $this->categories->addCategory($data->title);
00192 }
00193 }
00194 }
00195 parent::loadFromDb($id);
00196 }
00197
00206 function isComplete()
00207 {
00208 if (strlen($this->title) && strlen($this->author) && strlen($this->questiontext) && $this->categories->getCategoryCount())
00209 {
00210 return 1;
00211 }
00212 else
00213 {
00214 return 0;
00215 }
00216 }
00217
00225 function saveToDb($original_id = "", $withanswers = true)
00226 {
00227 global $ilDB;
00228 $complete = 0;
00229 if ($this->isComplete())
00230 {
00231 $complete = 1;
00232 }
00233 if ($original_id)
00234 {
00235 $original_id = $ilDB->quote($original_id);
00236 }
00237 else
00238 {
00239 $original_id = "NULL";
00240 }
00241
00242 include_once("./Services/RTE/classes/class.ilRTE.php");
00243 ilRTE::_cleanupMediaObjectUsage($this->questiontext, "spl:html",
00244 $this->getId());
00245
00246 if ($this->id == -1)
00247 {
00248
00249 $now = getdate();
00250 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00251 $query = sprintf("INSERT INTO survey_question (question_id, questiontype_fi, obj_fi, owner_fi, title, description, author, questiontext, obligatory, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00252 $ilDB->quote($this->getQuestionType()),
00253 $ilDB->quote($this->obj_id),
00254 $ilDB->quote($this->owner),
00255 $ilDB->quote($this->title),
00256 $ilDB->quote($this->description),
00257 $ilDB->quote($this->author),
00258 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($this->questiontext, 0)),
00259 $ilDB->quote(sprintf("%d", $this->obligatory)),
00260 $ilDB->quote("$complete"),
00261 $ilDB->quote($created),
00262 $original_id
00263 );
00264 $result = $ilDB->query($query);
00265 if ($result == DB_OK)
00266 {
00267 $this->id = $ilDB->getLastInsertId();
00268 $query = sprintf("INSERT INTO survey_question_nominal (question_fi, subtype, orientation) VALUES (%s, %s, %s)",
00269 $ilDB->quote($this->id . ""),
00270 $ilDB->quote($this->getSubType() . ""),
00271 $ilDB->quote(sprintf("%d", $this->orientation))
00272 );
00273 $ilDB->query($query);
00274 }
00275 }
00276 else
00277 {
00278
00279 $query = sprintf("UPDATE survey_question SET title = %s, description = %s, author = %s, questiontext = %s, obligatory = %s, complete = %s WHERE question_id = %s",
00280 $ilDB->quote($this->title),
00281 $ilDB->quote($this->description),
00282 $ilDB->quote($this->author),
00283 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($this->questiontext, 0)),
00284 $ilDB->quote(sprintf("%d", $this->obligatory)),
00285 $ilDB->quote("$complete"),
00286 $ilDB->quote($this->id)
00287 );
00288 $result = $ilDB->query($query);
00289 $query = sprintf("UPDATE survey_question_nominal SET subtype = %s, orientation = %s WHERE question_fi = %s",
00290 $ilDB->quote($this->getSubType() . ""),
00291 $ilDB->quote(sprintf("%d", $this->orientation)),
00292 $ilDB->quote($this->id . "")
00293 );
00294 $result = $ilDB->query($query);
00295 }
00296 if ($result == DB_OK)
00297 {
00298
00299 $this->saveMaterialsToDb();
00300 if ($withanswers)
00301 {
00302 $this->saveCategoriesToDb();
00303 }
00304 }
00305 parent::saveToDb($original_id);
00306 }
00307
00317 function from_xml($xml_text)
00318 {
00319 $result = false;
00320 if (!empty($this->domxml))
00321 {
00322 $this->domxml->free();
00323 }
00324 $xml_text = preg_replace("/>\s*?</", "><", $xml_text);
00325 $this->domxml = domxml_open_mem($xml_text);
00326 if (!empty($this->domxml))
00327 {
00328 $root = $this->domxml->document_element();
00329 $item = $root->first_child();
00330 $this->setTitle($item->get_attribute("title"));
00331 $this->gaps = array();
00332 $itemnodes = $item->child_nodes();
00333 foreach ($itemnodes as $index => $node)
00334 {
00335 switch ($node->node_name())
00336 {
00337 case "qticomment":
00338 $comment = $node->get_content();
00339 if (strpos($comment, "ILIAS Version=") !== false)
00340 {
00341 }
00342 elseif (strpos($comment, "Questiontype=") !== false)
00343 {
00344 }
00345 elseif (strpos($comment, "Author=") !== false)
00346 {
00347 $comment = str_replace("Author=", "", $comment);
00348 $this->setAuthor($comment);
00349 }
00350 else
00351 {
00352 $this->setDescription($comment);
00353 }
00354 break;
00355 case "itemmetadata":
00356 $qtimetadata = $node->first_child();
00357 $metadata_fields = $qtimetadata->child_nodes();
00358 foreach ($metadata_fields as $index => $metadata_field)
00359 {
00360 $fieldlabel = $metadata_field->first_child();
00361 $fieldentry = $fieldlabel->next_sibling();
00362 switch ($fieldlabel->get_content())
00363 {
00364 case "obligatory":
00365 $this->setObligatory($fieldentry->get_content());
00366 break;
00367 case "orientation":
00368 $this->setOrientation($fieldentry->get_content());
00369 break;
00370 }
00371 }
00372 break;
00373 case "presentation":
00374 $flow = $node->first_child();
00375 $flownodes = $flow->child_nodes();
00376 foreach ($flownodes as $idx => $flownode)
00377 {
00378 if (strcmp($flownode->node_name(), "material") == 0)
00379 {
00380 $mattext = $flownode->first_child();
00381 $this->setQuestiontext($mattext->get_content());
00382 }
00383 elseif (strcmp($flownode->node_name(), "response_lid") == 0)
00384 {
00385 $ident = $flownode->get_attribute("ident");
00386 if (strcmp($ident, "MCSR") == 0)
00387 {
00388 $this->setSubtype(SUBTYPE_MCSR);
00389 }
00390 else
00391 {
00392 $this->setSubtype(SUBTYPE_MCMR);
00393 }
00394 $shuffle = "";
00395 $response_lid_nodes = $flownode->child_nodes();
00396 foreach ($response_lid_nodes as $resp_lid_id => $resp_lid_node)
00397 {
00398 switch ($resp_lid_node->node_name())
00399 {
00400 case "render_choice":
00401 $render_choice = $resp_lid_node;
00402 $labels = $render_choice->child_nodes();
00403 foreach ($labels as $lidx => $response_label)
00404 {
00405 $material = $response_label->first_child();
00406 $mattext = $material->first_child();
00407 $shuf = 0;
00408 $this->categories->addCategoryAtPosition($mattext->get_content(), $response_label->get_attribute("ident"));
00409 }
00410 break;
00411 case "material":
00412 $matlabel = $resp_lid_node->get_attribute("label");
00413 $mattype = $resp_lid_node->first_child();
00414 if (strcmp($mattype->node_name(), "mattext") == 0)
00415 {
00416 $material = $mattype->get_content();
00417 if ($material)
00418 {
00419 if ($this->getId() < 1)
00420 {
00421 $this->saveToDb();
00422 }
00423 $this->setMaterial($material, true, $matlabel);
00424 }
00425 }
00426 break;
00427 }
00428 }
00429 }
00430 }
00431 break;
00432 }
00433 }
00434 $result = true;
00435 }
00436 return $result;
00437 }
00438
00448 function to_xml($a_include_header = true, $obligatory_state = "")
00449 {
00450 include_once("./classes/class.ilXmlWriter.php");
00451 $a_xml_writer = new ilXmlWriter;
00452
00453 $a_xml_writer->xmlHeader();
00454 $a_xml_writer->xmlStartTag("questestinterop");
00455 $attrs = array(
00456 "ident" => $this->getId(),
00457 "title" => $this->getTitle()
00458 );
00459 $a_xml_writer->xmlStartTag("item", $attrs);
00460
00461 $a_xml_writer->xmlElement("qticomment", NULL, $this->getDescription());
00462 $a_xml_writer->xmlElement("qticomment", NULL, "ILIAS Version=".$this->ilias->getSetting("ilias_version"));
00463 $a_xml_writer->xmlElement("qticomment", NULL, "Questiontype=".NOMINAL_QUESTION_IDENTIFIER);
00464 $a_xml_writer->xmlElement("qticomment", NULL, "Author=".$this->getAuthor());
00465
00466 $a_xml_writer->xmlStartTag("itemmetadata");
00467 $a_xml_writer->xmlStartTag("qtimetadata");
00468 $a_xml_writer->xmlStartTag("qtimetadatafield");
00469 $a_xml_writer->xmlElement("fieldlabel", NULL, "obligatory");
00470 if (strcmp($obligatory_state, "") != 0)
00471 {
00472 $this->setObligatory($obligatory_state);
00473 }
00474 $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->getObligatory()));
00475 $a_xml_writer->xmlEndTag("qtimetadatafield");
00476 $a_xml_writer->xmlStartTag("qtimetadatafield");
00477 $a_xml_writer->xmlElement("fieldlabel", NULL, "orientation");
00478 $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->getOrientation()));
00479 $a_xml_writer->xmlEndTag("qtimetadatafield");
00480 $a_xml_writer->xmlEndTag("qtimetadata");
00481 $a_xml_writer->xmlEndTag("itemmetadata");
00482
00483
00484 $attrs = array(
00485 "label" => $this->getTitle()
00486 );
00487 $a_xml_writer->xmlStartTag("presentation", $attrs);
00488
00489 $a_xml_writer->xmlStartTag("flow");
00490
00491 $this->addQTIMaterial($a_xml_writer, $this->getQuestiontext());
00492
00493 $ident = "MCMR";
00494 $rcardinality = "Multiple";
00495 if ($this->getSubtype() == SUBTYPE_MCSR)
00496 {
00497 $ident = "MCSR";
00498 $rcardinality = "Single";
00499 }
00500 $attrs = array(
00501 "ident" => $ident,
00502 "rcardinality" => $rcardinality
00503 );
00504 $a_xml_writer->xmlStartTag("response_lid", $attrs);
00505
00506 if (count($this->material))
00507 {
00508 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $this->material["internal_link"], $matches))
00509 {
00510 $attrs = array(
00511 "label" => $this->material["title"]
00512 );
00513 $a_xml_writer->xmlStartTag("material", $attrs);
00514 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00515 if (strcmp($matches[1], "") != 0)
00516 {
00517 $intlink = $this->material["internal_link"];
00518 }
00519 $a_xml_writer->xmlElement("mattext", NULL, $intlink);
00520 $a_xml_writer->xmlEndTag("material");
00521 }
00522 }
00523
00524 $attrs = array(
00525 "shuffle" => "no"
00526 );
00527 $a_xml_writer->xmlStartTag("render_choice", $attrs);
00528
00529
00530 for ($index = 0; $index < $this->categories->getCategoryCount(); $index++)
00531 {
00532 $category = $this->categories->getCategory($index);
00533 $attrs = array(
00534 "ident" => "$index"
00535 );
00536 $a_xml_writer->xmlStartTag("response_label", $attrs);
00537 $a_xml_writer->xmlStartTag("material");
00538 $a_xml_writer->xmlElement("mattext", NULL, $category);
00539 $a_xml_writer->xmlEndTag("material");
00540 $a_xml_writer->xmlEndTag("response_label");
00541 }
00542 $a_xml_writer->xmlEndTag("render_choice");
00543 $a_xml_writer->xmlEndTag("response_lid");
00544 $a_xml_writer->xmlEndTag("flow");
00545 $a_xml_writer->xmlEndTag("presentation");
00546 $a_xml_writer->xmlEndTag("item");
00547 $a_xml_writer->xmlEndTag("questestinterop");
00548
00549 $xml = $a_xml_writer->xmlDumpMem(FALSE);
00550 if (!$a_include_header)
00551 {
00552 $pos = strpos($xml, "?>");
00553 $xml = substr($xml, $pos + 2);
00554 }
00555 return $xml;
00556 }
00557
00558 function syncWithOriginal()
00559 {
00560 global $ilDB;
00561 if ($this->original_id)
00562 {
00563 $complete = 0;
00564 if ($this->isComplete())
00565 {
00566 $complete = 1;
00567 }
00568 $query = sprintf("UPDATE survey_question SET title = %s, description = %s, author = %s, questiontext = %s, obligatory = %s, complete = %s WHERE question_id = %s",
00569 $ilDB->quote($this->title . ""),
00570 $ilDB->quote($this->description . ""),
00571 $ilDB->quote($this->author . ""),
00572 $ilDB->quote($this->questiontext . ""),
00573 $ilDB->quote(sprintf("%d", $this->obligatory) . ""),
00574 $ilDB->quote($complete . ""),
00575 $ilDB->quote($this->original_id . "")
00576 );
00577 $result = $ilDB->query($query);
00578 $query = sprintf("UPDATE survey_question_nominal SET subtype = %s, orientation = %s WHERE question_fi = %s",
00579 $ilDB->quote($this->getSubType() . ""),
00580 $ilDB->quote($this->getOrientation() . ""),
00581 $ilDB->quote($this->original_id . "")
00582 );
00583 $result = $ilDB->query($query);
00584 if ($result == DB_OK) {
00585
00586
00587
00588 $query = sprintf("DELETE FROM survey_variable WHERE question_fi = %s",
00589 $ilDB->quote($this->original_id . "")
00590 );
00591 $result = $ilDB->query($query);
00592
00593
00594 for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
00595 {
00596 $category_id = $this->saveCategoryToDb($this->categories->getCategory($i));
00597 $query = sprintf("INSERT INTO survey_variable (variable_id, category_fi, question_fi, value1, sequence, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, NULL)",
00598 $ilDB->quote($category_id . ""),
00599 $ilDB->quote($this->original_id . ""),
00600 $ilDB->quote(($i + 1) . ""),
00601 $ilDB->quote($i . "")
00602 );
00603 $answer_result = $ilDB->query($query);
00604 }
00605 }
00606 }
00607 parent::syncWithOriginal();
00608 }
00609
00618 function getQuestionType()
00619 {
00620 return 1;
00621 }
00622
00631 function getAdditionalTableName()
00632 {
00633 return "survey_question_nominal";
00634 }
00635
00636 function checkUserInput($post_data)
00637 {
00638
00639
00640 $entered_value = $post_data[$this->getId() . "_value"];
00641 if ($this->getSubType() == SUBTYPE_MCMR)
00642 {
00643 if (!$this->getObligatory()) return "";
00644
00645 if (!is_array($entered_value))
00646 {
00647 return $this->lng->txt("nominal_question_mr_not_checked");
00648 }
00649 }
00650 else
00651 {
00652 if ((!$this->getObligatory()) && (strlen($entered_value) == 0)) return "";
00653
00654 if (strlen($entered_value) == 0) return $this->lng->txt("nominal_question_not_checked");
00655 }
00656 return "";
00657 }
00658
00659 function saveUserInput($post_data, $survey_id, $user_id, $anonymous_id)
00660 {
00661 global $ilDB;
00662
00663 if (is_array($post_data[$this->getId() . "_value"]))
00664 {
00665 foreach ($post_data[$this->getId() . "_value"] as $value)
00666 {
00667 $entered_value = $value;
00668 if (strlen($entered_value) > 0)
00669 {
00670 $entered_value = $ilDB->quote($entered_value . "");
00671 $query = sprintf("INSERT INTO survey_answer (answer_id, survey_fi, question_fi, user_fi, anonymous_id, value, textanswer, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
00672 $ilDB->quote($survey_id . ""),
00673 $ilDB->quote($this->getId() . ""),
00674 $ilDB->quote($user_id . ""),
00675 $ilDB->quote($anonymous_id . ""),
00676 $entered_value,
00677 "NULL"
00678 );
00679 $result = $ilDB->query($query);
00680 }
00681 }
00682 }
00683 else
00684 {
00685 $entered_value = $post_data[$this->getId() . "_value"];
00686 if (strlen($entered_value) == 0) return;
00687 $entered_value = $ilDB->quote($entered_value . "");
00688 $query = sprintf("INSERT INTO survey_answer (answer_id, survey_fi, question_fi, user_fi, anonymous_id, value, textanswer, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
00689 $ilDB->quote($survey_id . ""),
00690 $ilDB->quote($this->getId() . ""),
00691 $ilDB->quote($user_id . ""),
00692 $ilDB->quote($anonymous_id . ""),
00693 $entered_value,
00694 "NULL"
00695 );
00696 $result = $ilDB->query($query);
00697 }
00698 }
00699
00700 function &getCumulatedResults($survey_id, $nr_of_users)
00701 {
00702 global $ilDB;
00703
00704 $question_id = $this->getId();
00705
00706 $result_array = array();
00707 $cumulated = array();
00708
00709 $query = sprintf("SELECT * FROM survey_answer WHERE question_fi = %s AND survey_fi = %s",
00710 $ilDB->quote($question_id),
00711 $ilDB->quote($survey_id)
00712 );
00713 $result = $ilDB->query($query);
00714 $numrows = $result->numRows();
00715
00716
00717 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
00718 {
00719 $cumulated["$row->value"]++;
00720 }
00721 asort($cumulated, SORT_NUMERIC);
00722 end($cumulated);
00723
00724 if ($this->getSubType() == SUBTYPE_MCMR)
00725 {
00726 $result_array["USERS_ANSWERED"] = $nr_of_users;
00727 $result_array["USERS_SKIPPED"] = 0;
00728 }
00729 else
00730 {
00731 $result_array["USERS_ANSWERED"] = $result->numRows();
00732 $result_array["USERS_SKIPPED"] = $nr_of_users - $result->numRows();
00733 }
00734 $result_array["MEDIAN"] = "";
00735 $result_array["ARITHMETIC_MEAN"] = "";
00736 $prefix = "";
00737 if (strcmp(key($cumulated), "") != 0)
00738 {
00739 $prefix = (key($cumulated)+1) . " - ";
00740 }
00741 $result_array["MODE"] = $prefix . $this->categories->getCategory(key($cumulated));
00742 $result_array["MODE_VALUE"] = key($cumulated)+1;
00743 $result_array["MODE_NR_OF_SELECTIONS"] = $cumulated[key($cumulated)];
00744 $result_array["QUESTION_TYPE"] = "SurveyNominalQuestion";
00745 $maxvalues = 0;
00746 for ($key = 0; $key < $this->categories->getCategoryCount(); $key++)
00747 {
00748 $maxvalues += $cumulated[$key];
00749 }
00750 for ($key = 0; $key < $this->categories->getCategoryCount(); $key++)
00751 {
00752 $percentage = 0;
00753 if ($numrows > 0)
00754 {
00755 if ($this->getSubType() == SUBTYPE_MCMR)
00756 {
00757 if ($maxvalues > 0)
00758 {
00759 $percentage = ($result_array["USERS_ANSWERED"] > 0) ? (float)((int)$cumulated[$key]/$result_array["USERS_ANSWERED"]) : 0;
00760 }
00761 }
00762 else
00763 {
00764 $percentage = ($numrows > 0) ? (float)((int)$cumulated[$key]/$numrows) : 0;
00765 }
00766 }
00767 $result_array["variables"][$key] = array("title" => $this->categories->getCategory($key), "selected" => (int)$cumulated[$key], "percentage" => $percentage);
00768 }
00769 return $result_array;
00770 }
00771 }
00772 ?>