• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

assessment/classes/class.assTextSubset.php

Go to the documentation of this file.
00001 <?php
00002  /*
00003    +----------------------------------------------------------------------------+
00004    | ILIAS open source                                                          |
00005    +----------------------------------------------------------------------------+
00006    | Copyright (c) 1998-2001 ILIAS open source, University of Cologne           |
00007    |                                                                            |
00008    | This program is free software; you can redistribute it and/or              |
00009    | modify it under the terms of the GNU General Public License                |
00010    | as published by the Free Software Foundation; either version 2             |
00011    | of the License, or (at your option) any later version.                     |
00012    |                                                                            |
00013    | This program is distributed in the hope that it will be useful,            |
00014    | but WITHOUT ANY WARRANTY; without even the implied warranty of             |
00015    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              |
00016    | GNU General Public License for more details.                               |
00017    |                                                                            |
00018    | You should have received a copy of the GNU General Public License          |
00019    | along with this program; if not, write to the Free Software                |
00020    | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
00021    +----------------------------------------------------------------------------+
00022 */
00023 include_once "./assessment/classes/class.assQuestion.php";
00024 include_once "./assessment/classes/inc.AssessmentConstants.php";
00025 
00038 class assTextSubset extends assQuestion
00039 {
00047         var $question;
00048 
00056         var $answers;
00057         
00065         var $correctanswers;
00066 
00074         var $text_rating;
00075 
00089         function assTextSubset(
00090                 $title = "",
00091                 $comment = "",
00092                 $author = "",
00093                 $owner = -1,
00094                 $question = ""
00095           )
00096         {
00097                 $this->assQuestion($title, $comment, $author, $owner);
00098                 $this->question = $question;
00099                 $this->answers = array();
00100                 $this->correctanswers = 0;
00101         }
00102 
00111         function isComplete()
00112         {
00113                 if (($this->title) and ($this->author) and ($this->question) and (count($this->answers) >= $this->correctanswers) and ($this->getMaximumPoints() > 0))
00114                 {
00115                         return true;
00116                 }
00117                         else
00118                 {
00119                         return false;
00120                 }
00121         }
00122 
00136         function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
00137         {
00138                 global $ilUser;
00139 
00140                 // empty session variable for imported xhtml mobs
00141                 unset($_SESSION["import_mob_xhtml"]);
00142                 $presentation = $item->getPresentation(); 
00143                 $duration = $item->getDuration();
00144                 $shuffle = 0;
00145                 $idents = array();
00146                 $now = getdate();
00147                 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00148                 $gaps = array();
00149                 foreach ($presentation->order as $entry)
00150                 {
00151                         switch ($entry["type"])
00152                         {
00153                                 case "response":
00154                                         $response = $presentation->response[$entry["index"]];
00155                                         if ($response->getResponseType() == RT_RESPONSE_STR)
00156                                         {
00157                                                 array_push($idents, $response->getIdent());
00158                                         }
00159                                         break;
00160                         }
00161                 }
00162                 $responses = array();
00163                 foreach ($item->resprocessing as $resprocessing)
00164                 {
00165                         foreach ($resprocessing->respcondition as $respcondition)
00166                         {
00167                                 $ident = "";
00168                                 $correctness = 1;
00169                                 $conditionvar = $respcondition->getConditionvar();
00170                                 foreach ($conditionvar->order as $order)
00171                                 {
00172                                         switch ($order["field"])
00173                                         {
00174                                                 case "varsubset":
00175                                                         $respident = $conditionvar->varsubset[$order["index"]]->getRespident();
00176                                                         $content = $conditionvar->varsubset[$order["index"]]->getContent();
00177                                                         if (!is_array($responses[$respident])) $responses[$respident] = array();
00178                                                         $vars = split(",", $content);
00179                                                         foreach ($vars as $var)
00180                                                         {
00181                                                                 array_push($responses[$respident], array("solution" => $var, "points" => ""));
00182                                                         }
00183                                                         break;
00184                                         }
00185                                 }
00186                                 foreach ($respcondition->setvar as $setvar)
00187                                 {
00188                                         if ((strcmp($setvar->getVarname(), "matches") == 0) && ($setvar->getAction() == ACTION_ADD))
00189                                         {
00190                                                 foreach ($responses[$respident] as $idx => $solutionarray)
00191                                                 {
00192                                                         if (strlen($solutionarray["points"] == 0))
00193                                                         {
00194                                                                 $responses[$respident][$idx]["points"] = $setvar->getContent();
00195                                                         }
00196                                                 }
00197                                         }
00198                                 }
00199                         }
00200                 }
00201 
00202                 $this->setTitle($item->getTitle());
00203                 $this->setComment($item->getComment());
00204                 $this->setAuthor($item->getAuthor());
00205                 $this->setOwner($ilUser->getId());
00206                 $this->setQuestion($this->QTIMaterialToString($item->getQuestiontext()));
00207                 $this->setObjId($questionpool_id);
00208                 $this->setEstimatedWorkingTime($duration["h"], $duration["m"], $duration["s"]);
00209                 $textrating = $item->getMetadataEntry("textrating");
00210                 if (strlen($textrating) == 0) $textrating = "ci";
00211                 $this->setTextRating($textgap_rating);
00212                 $this->setCorrectAnswers($item->getMetadataEntry("correctanswers"));
00213                 $response = current($responses);
00214                 $counter = 0;
00215                 if (is_array($response))
00216                 {
00217                         foreach ($response as $answer)
00218                         {
00219                                 $this->addAnswer($answer["solution"], $answer["points"], $counter);
00220                                 $counter++;
00221                         }
00222                 }
00223                 $this->saveToDb();
00224                 if (count($item->suggested_solutions))
00225                 {
00226                         foreach ($item->suggested_solutions as $suggested_solution)
00227                         {
00228                                 $this->setSuggestedSolution($suggested_solution["solution"]->getContent(), $suggested_solution["gap_index"], true);
00229                         }
00230                         $this->saveToDb();
00231                 }
00232                 // handle the import of media objects in XHTML code
00233                 if (is_array($_SESSION["import_mob_xhtml"]))
00234                 {
00235                         include_once "./content/classes/Media/class.ilObjMediaObject.php";
00236                         include_once "./Services/RTE/classes/class.ilRTE.php";
00237                         foreach ($_SESSION["import_mob_xhtml"] as $mob)
00238                         {
00239                                 if ($tst_id > 0)
00240                                 {
00241                                         include_once "./assessment/classes/class.ilObjTest.php";
00242                                         $importfile = ilObjTest::_getImportDirectory() . "/" . $_SESSION["tst_import_subdir"] . "/" . $mob["uri"];
00243                                 }
00244                                 else
00245                                 {
00246                                         include_once "./assessment/classes/class.ilObjQuestionPool.php";
00247                                         $importfile = ilObjQuestionPool::_getImportDirectory() . "/" . $_SESSION["qpl_import_subdir"] . "/" . $mob["uri"];
00248                                 }
00249                                 $media_object =& ilObjMediaObject::_saveTempFileAsMediaObject(basename($importfile), $importfile, FALSE);
00250                                 ilObjMediaObject::_saveUsage($media_object->getId(), "qpl:html", $this->getId());
00251                                 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getQuestion()), 1));
00252                         }
00253                         $this->saveToDb();
00254                 }
00255                 if ($tst_id > 0)
00256                 {
00257                         $q_1_id = $this->getId();
00258                         $question_id = $this->duplicate(true);
00259                         $tst_object->questions[$question_counter++] = $question_id;
00260                         $import_mapping[$item->getIdent()] = array("pool" => $q_1_id, "test" => $question_id);
00261                 }
00262                 else
00263                 {
00264                         $import_mapping[$item->getIdent()] = array("pool" => $this->getId(), "test" => 0);
00265                 }
00266                 //$ilLog->write(strftime("%D %T") . ": finished import multiple choice question (single response)");
00267         }
00268 
00278         function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
00279         {
00280                 include_once("./classes/class.ilXmlWriter.php");
00281                 $a_xml_writer = new ilXmlWriter;
00282                 // set xml header
00283                 $a_xml_writer->xmlHeader();
00284                 $a_xml_writer->xmlStartTag("questestinterop");
00285                 $attrs = array(
00286                         "ident" => "il_".IL_INST_ID."_qst_".$this->getId(),
00287                         "title" => $this->getTitle()
00288                 );
00289                 $a_xml_writer->xmlStartTag("item", $attrs);
00290                 // add question description
00291                 $a_xml_writer->xmlElement("qticomment", NULL, $this->getComment());
00292                 // add estimated working time
00293                 $workingtime = $this->getEstimatedWorkingTime();
00294                 $duration = sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]);
00295                 $a_xml_writer->xmlElement("duration", NULL, $duration);
00296                 // add ILIAS specific metadata
00297                 $a_xml_writer->xmlStartTag("itemmetadata");
00298                 $a_xml_writer->xmlStartTag("qtimetadata");
00299                 $a_xml_writer->xmlStartTag("qtimetadatafield");
00300                 $a_xml_writer->xmlElement("fieldlabel", NULL, "ILIAS_VERSION");
00301                 $a_xml_writer->xmlElement("fieldentry", NULL, $this->ilias->getSetting("ilias_version"));
00302                 $a_xml_writer->xmlEndTag("qtimetadatafield");
00303                 $a_xml_writer->xmlStartTag("qtimetadatafield");
00304                 $a_xml_writer->xmlElement("fieldlabel", NULL, "QUESTIONTYPE");
00305                 $a_xml_writer->xmlElement("fieldentry", NULL, TEXTSUBSET_QUESTION_IDENTIFIER);
00306                 $a_xml_writer->xmlEndTag("qtimetadatafield");
00307                 $a_xml_writer->xmlStartTag("qtimetadatafield");
00308                 $a_xml_writer->xmlElement("fieldlabel", NULL, "AUTHOR");
00309                 $a_xml_writer->xmlElement("fieldentry", NULL, $this->getAuthor());
00310                 $a_xml_writer->xmlEndTag("qtimetadatafield");
00311                 $a_xml_writer->xmlStartTag("qtimetadatafield");
00312                 $a_xml_writer->xmlElement("fieldlabel", NULL, "textrating");
00313                 $a_xml_writer->xmlElement("fieldentry", NULL, $this->getTextRating());
00314                 $a_xml_writer->xmlEndTag("qtimetadatafield");
00315                 $a_xml_writer->xmlStartTag("qtimetadatafield");
00316                 $a_xml_writer->xmlElement("fieldlabel", NULL, "correctanswers");
00317                 $a_xml_writer->xmlElement("fieldentry", NULL, $this->getCorrectAnswers());
00318                 $a_xml_writer->xmlEndTag("qtimetadatafield");
00319                 $a_xml_writer->xmlStartTag("qtimetadatafield");
00320                 $a_xml_writer->xmlElement("fieldlabel", NULL, "points");
00321                 $a_xml_writer->xmlElement("fieldentry", NULL, $this->getPoints());
00322                 $a_xml_writer->xmlEndTag("qtimetadatafield");
00323                 $a_xml_writer->xmlEndTag("qtimetadata");
00324                 $a_xml_writer->xmlEndTag("itemmetadata");
00325 
00326                 // PART I: qti presentation
00327                 $attrs = array(
00328                         "label" => $this->getTitle()
00329                 );
00330                 $a_xml_writer->xmlStartTag("presentation", $attrs);
00331                 // add flow to presentation
00332                 $a_xml_writer->xmlStartTag("flow");
00333                 // add material with question text to presentation
00334                 $this->addQTIMaterial($a_xml_writer, $this->getQuestion());
00335                 // add answers to presentation
00336                 for ($counter = 1; $counter <= $this->getCorrectAnswers(); $counter++)
00337                 {
00338                         $attrs = array(
00339                                 "ident" => "TEXTSUBSET_" . sprintf("%02d", $counter),
00340                                 "rcardinality" => "Single"
00341                         );
00342                         $a_xml_writer->xmlStartTag("response_str", $attrs);
00343                         $solution = $this->getSuggestedSolution(0);
00344                         if (count($solution))
00345                         {
00346                                 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00347                                 {
00348                                         $a_xml_writer->xmlStartTag("material");
00349                                         $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00350                                         if (strcmp($matches[1], "") != 0)
00351                                         {
00352                                                 $intlink = $solution["internal_link"];
00353                                         }
00354                                         $attrs = array(
00355                                                 "label" => "suggested_solution"
00356                                         );
00357                                         $a_xml_writer->xmlElement("mattext", $attrs, $intlink);
00358                                         $a_xml_writer->xmlEndTag("material");
00359                                 }
00360                         }
00361                         // shuffle output
00362                         $attrs = array(
00363                                 "fibtype" => "String",
00364                                 "columns" => $this->getMaxTextboxWidth()
00365                         );
00366                         $a_xml_writer->xmlStartTag("render_fib", $attrs);
00367                         $a_xml_writer->xmlEndTag("render_fib");
00368                         $a_xml_writer->xmlEndTag("response_str");
00369                 }
00370                 
00371                 $a_xml_writer->xmlEndTag("flow");
00372                 $a_xml_writer->xmlEndTag("presentation");
00373                 
00374                 // PART II: qti resprocessing
00375                 $a_xml_writer->xmlStartTag("resprocessing");
00376                 $a_xml_writer->xmlStartTag("outcomes");
00377                 $a_xml_writer->xmlStartTag("decvar");
00378                 $a_xml_writer->xmlEndTag("decvar");
00379                 $attribs = array(
00380                         "varname" => "matches",
00381                         "defaultval" => "0"
00382                 );
00383                 $a_xml_writer->xmlElement("decvar", $attribs, NULL);
00384                 $a_xml_writer->xmlEndTag("outcomes");
00385                 // add response conditions
00386                 for ($counter = 1; $counter <= $this->getCorrectAnswers(); $counter++)
00387                 {
00388                         $scoregroups =& $this->joinAnswers();
00389                         foreach ($scoregroups as $points => $scoreanswers)
00390                         {
00391                                 $attrs = array(
00392                                         "continue" => "Yes"
00393                                 );
00394                                 $a_xml_writer->xmlStartTag("respcondition", $attrs);
00395                                 // qti conditionvar
00396                                 $a_xml_writer->xmlStartTag("conditionvar");
00397                                 $attrs = array(
00398                                         "respident" => "TEXTSUBSET_" . sprintf("%02d", $counter)
00399                                 );
00400                                 $a_xml_writer->xmlElement("varsubset", $attrs, join(",", $scoreanswers));
00401                                 $a_xml_writer->xmlEndTag("conditionvar");
00402                                 // qti setvar
00403                                 $attrs = array(
00404                                         "varname" => "matches",
00405                                         "action" => "Add"
00406                                 );
00407                                 $a_xml_writer->xmlElement("setvar", $attrs, $points);
00408                                 // qti displayfeedback
00409                                 $attrs = array(
00410                                         "feedbacktype" => "Response",
00411                                         "linkrefid" => "Matches_" . sprintf("%02d", $counter)
00412                                 );
00413                                 $a_xml_writer->xmlElement("displayfeedback", $attrs);
00414                                 $a_xml_writer->xmlEndTag("respcondition");
00415                         }
00416                 }
00417                 $a_xml_writer->xmlEndTag("resprocessing");
00418 
00419                 // PART III: qti itemfeedback
00420                 for ($counter = 1; $counter <= $this->getCorrectAnswers(); $counter++)
00421                 {
00422                         $attrs = array(
00423                                 "ident" => "Matches_" . sprintf("%02d", $counter),
00424                                 "view" => "All"
00425                         );
00426                         $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
00427                         // qti flow_mat
00428                         $a_xml_writer->xmlStartTag("flow_mat");
00429                         $a_xml_writer->xmlStartTag("material");
00430                         $a_xml_writer->xmlElement("mattext");
00431                         $a_xml_writer->xmlEndTag("material");
00432                         $a_xml_writer->xmlEndTag("flow_mat");
00433                         $a_xml_writer->xmlEndTag("itemfeedback");
00434                 }
00435                 
00436                 $a_xml_writer->xmlEndTag("item");
00437                 $a_xml_writer->xmlEndTag("questestinterop");
00438 
00439                 $xml = $a_xml_writer->xmlDumpMem(FALSE);
00440                 if (!$a_include_header)
00441                 {
00442                         $pos = strpos($xml, "?>");
00443                         $xml = substr($xml, $pos + 2);
00444                 }
00445                 return $xml;
00446         }
00447 
00456         function saveToDb($original_id = "")
00457         {
00458                 global $ilDB;
00459 
00460                 $complete = 0;
00461                 if ($this->isComplete())
00462                 {
00463                         $complete = 1;
00464                 }
00465                 $estw_time = $this->getEstimatedWorkingTime();
00466                 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00467 
00468                 if ($original_id)
00469                 {
00470                         $original_id = $ilDB->quote($original_id);
00471                 }
00472                 else
00473                 {
00474                         $original_id = "NULL";
00475                 }
00476 
00477                 // cleanup RTE images which are not inserted into the question text
00478                 include_once("./Services/RTE/classes/class.ilRTE.php");
00479                 ilRTE::_cleanupMediaObjectUsage($this->question, "qpl:html",
00480                         $this->getId());
00481 
00482                 if ($this->id == -1)
00483                 {
00484                         // Neuen Datensatz schreiben
00485                         $now = getdate();
00486                         $question_type = $this->getQuestionType();
00487                         $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00488                         $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, points, working_time, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00489                                 $ilDB->quote($question_type),
00490                                 $ilDB->quote($this->obj_id),
00491                                 $ilDB->quote($this->title),
00492                                 $ilDB->quote($this->comment),
00493                                 $ilDB->quote($this->author),
00494                                 $ilDB->quote($this->owner),
00495                                 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($this->question, 0)),
00496                                 $ilDB->quote($this->getMaximumPoints() . ""),
00497                                 $ilDB->quote($estw_time),
00498                                 $ilDB->quote("$complete"),
00499                                 $ilDB->quote($created),
00500                                 $original_id
00501                         );
00502                         $result = $ilDB->query($query);
00503                         
00504                         if ($result == DB_OK)
00505                         {
00506                                 $this->id = $ilDB->getLastInsertId();
00507                                 $query = sprintf("INSERT INTO qpl_question_textsubset (question_fi, textgap_rating, correctanswers) VALUES (%s, %s, %s)",
00508                                         $ilDB->quote($this->id . ""),
00509                                         $ilDB->quote($this->getTextRating() . ""),
00510                                         $ilDB->quote($this->getCorrectAnswers() . "")
00511                                 );
00512                                 $ilDB->query($query);
00513 
00514                                 // create page object of question
00515                                 $this->createPageObject();
00516 
00517                                 // Falls die Frage in einen Test eingefügt werden soll, auch diese Verbindung erstellen
00518                                 if ($this->getTestId() > 0)
00519                                 {
00520                                 $this->insertIntoTest($this->getTestId());
00521                                 }
00522                         }
00523                 }
00524                 else
00525                 {
00526                         // Vorhandenen Datensatz aktualisieren
00527                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, points = %s, working_time=%s, complete = %s WHERE question_id = %s",
00528                                 $ilDB->quote($this->obj_id. ""),
00529                                 $ilDB->quote($this->title),
00530                                 $ilDB->quote($this->comment),
00531                                 $ilDB->quote($this->author),
00532                                 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($this->question, 0)),
00533                                 $ilDB->quote($this->getMaximumPoints() . ""),
00534                                 $ilDB->quote($estw_time),
00535                                 $ilDB->quote("$complete"),
00536                                 $ilDB->quote($this->id)
00537                         );
00538                         $result = $ilDB->query($query);
00539                         $query = sprintf("UPDATE qpl_question_textsubset SET textgap_rating = %s, correctanswers = %s WHERE question_fi = %s",
00540                                 $ilDB->quote($this->getTextRating() . ""),
00541                                 $ilDB->quote($this->getCorrectAnswers() . ""),
00542                                 $ilDB->quote($this->id . "")
00543                         );
00544                         $result = $ilDB->query($query);
00545                 }
00546                 if ($result == DB_OK)
00547                 {
00548                         // Write Ranges to the database
00549                         
00550                         // 1. delete old ranges
00551                         $query = sprintf("DELETE FROM qpl_answer_textsubset WHERE question_fi = %s",
00552                                 $ilDB->quote($this->id)
00553                         );
00554                         $result = $ilDB->query($query);
00555 
00556                         // 2. write ranges
00557                         foreach ($this->answers as $key => $value)
00558                         {
00559                                 $answer_obj = $this->answers[$key];
00560                                 $query = sprintf("INSERT INTO qpl_answer_textsubset (answer_id, question_fi, answertext, points, aorder) VALUES (NULL, %s, %s, %s, %s)",
00561                                         $ilDB->quote($this->id),
00562                                         $ilDB->quote($answer_obj->getAnswertext()),
00563                                         $ilDB->quote($answer_obj->getPoints() . ""),
00564                                         $ilDB->quote($answer_obj->getOrder() . "")
00565                                 );
00566                                 $answer_result = $ilDB->query($query);
00567                         }
00568                 }
00569                 parent::saveToDb($original_id);
00570         }
00571 
00581         function loadFromDb($question_id)
00582         {
00583                 global $ilDB;
00584 
00585     $query = sprintf("SELECT qpl_questions.*, qpl_question_textsubset.* FROM qpl_questions, qpl_question_textsubset WHERE question_id = %s AND qpl_questions.question_id = qpl_question_textsubset.question_fi",
00586                         $ilDB->quote($question_id)
00587                 );
00588                 $result = $ilDB->query($query);
00589                 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00590                 {
00591                         if ($result->numRows() == 1)
00592                         {
00593                                 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00594                                 $this->id = $question_id;
00595                                 $this->title = $data->title;
00596                                 $this->comment = $data->comment;
00597                                 $this->solution_hint = $data->solution_hint;
00598                                 $this->original_id = $data->original_id;
00599                                 $this->obj_id = $data->obj_fi;
00600                                 $this->author = $data->author;
00601                                 $this->owner = $data->owner;
00602                                 $this->points = $data->points;
00603                                 include_once("./Services/RTE/classes/class.ilRTE.php");
00604                                 $this->question = ilRTE::_replaceMediaObjectImageSrc($data->question_text, 1);
00605                                 $this->correctanswers = $data->correctanswers;
00606                                 $this->text_rating = $data->textgap_rating;
00607                                 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00608                         }
00609 
00610                         $query = sprintf("SELECT * FROM qpl_answer_textsubset WHERE question_fi = %s ORDER BY aorder ASC",
00611                                 $ilDB->quote($question_id)
00612                         );
00613                         $result = $ilDB->query($query);
00614 
00615                         include_once "./assessment/classes/class.assAnswerSimple.php";
00616                         if (strcmp(strtolower(get_class($result)), db_result) == 0)
00617                         {
00618                                 while ($data = $result->fetchRow(DB_FETCHMODE_ASSOC))
00619                                 {
00620                                         array_push($this->answers, new ASS_AnswerSimple($data["answertext"], $data["points"], $data["aorder"]));
00621                                 }
00622                         }
00623                 }
00624                 parent::loadFromDb($question_id);
00625         }
00626 
00627 
00637         function setQuestion($question = "")
00638         {
00639                 $this->question = $question;
00640         }
00641 
00649         function addAnswer($answertext, $points, $answerorder)
00650         {
00651                 include_once "./assessment/classes/class.assAnswerSimple.php";
00652                 array_push($this->answers, new ASS_AnswerSimple($answertext, $points, $answerorder));
00653         }
00654         
00662         function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00663         {
00664                 if ($this->id <= 0)
00665                 {
00666                         // The question has not been saved. It cannot be duplicated
00667                         return;
00668                 }
00669                 // duplicate the question in database
00670                 $this_id = $this->getId();
00671                 $clone = $this;
00672                 include_once ("./assessment/classes/class.assQuestion.php");
00673                 $original_id = assQuestion::_getOriginalId($this->id);
00674                 $clone->id = -1;
00675                 if ($title)
00676                 {
00677                         $clone->setTitle($title);
00678                 }
00679 
00680                 if ($author)
00681                 {
00682                         $clone->setAuthor($author);
00683                 }
00684                 if ($owner)
00685                 {
00686                         $clone->setOwner($owner);
00687                 }
00688 
00689                 if ($for_test)
00690                 {
00691                         $clone->saveToDb($original_id);
00692                 }
00693                 else
00694                 {
00695                         $clone->saveToDb();
00696                 }
00697 
00698                 // copy question page content
00699                 $clone->copyPageOfQuestion($this_id);
00700                 // copy XHTML media objects
00701                 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
00702 
00703                 return $clone->id;
00704         }
00705 
00713         function copyObject($target_questionpool, $title = "")
00714         {
00715                 if ($this->id <= 0)
00716                 {
00717                         // The question has not been saved. It cannot be duplicated
00718                         return;
00719                 }
00720                 // duplicate the question in database
00721                 $clone = $this;
00722                 include_once ("./assessment/classes/class.assQuestion.php");
00723                 $original_id = assQuestion::_getOriginalId($this->id);
00724                 $clone->id = -1;
00725                 $source_questionpool = $this->getObjId();
00726                 $clone->setObjId($target_questionpool);
00727                 if ($title)
00728                 {
00729                         $clone->setTitle($title);
00730                 }
00731                 $clone->saveToDb();
00732 
00733                 // copy question page content
00734                 $clone->copyPageOfQuestion($original_id);
00735                 // copy XHTML media objects
00736                 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
00737 
00738                 return $clone->id;
00739         }
00740         
00750         function getQuestion()
00751         {
00752                 return $this->question;
00753         }
00754 
00764         function getAnswerCount()
00765         {
00766                 return count($this->answers);
00767         }
00768 
00780         function getAnswer($index = 0)
00781         {
00782                 if ($index < 0) return NULL;
00783                 if (count($this->answers) < 1) return NULL;
00784                 if ($index >= count($this->answers)) return NULL;
00785 
00786                 return $this->answers[$index];
00787         }
00788 
00799         function deleteAnswer($index = 0)
00800         {
00801                 if ($index < 0) return;
00802                 if (count($this->answers) < 1) return;
00803                 if ($index >= count($this->answers)) return;
00804                 unset($this->answers[$index]);
00805                 $this->answers = array_values($this->answers);
00806                 for ($i = 0; $i < count($this->answers); $i++)
00807                 {
00808                         if ($this->answers[$i]->getOrder() > $index)
00809                         {
00810                                 $this->answers[$i]->setOrder($i);
00811                         }
00812                 }
00813         }
00814 
00823         function flushAnswers()
00824         {
00825                 $this->answers = array();
00826         }
00827 
00836         function getMaximumPoints()
00837         {
00838                 $points = array();
00839                 foreach ($this->answers as $answer)
00840                 {
00841                         if ($answer->getPoints() > 0)
00842                         {
00843                                 array_push($points, $answer->getPoints());
00844                         }
00845                 }
00846                 rsort($points, SORT_NUMERIC);
00847                 $maxpoints = 0;
00848                 for ($counter = 0; $counter < $this->getCorrectAnswers(); $counter++)
00849                 {
00850                         $maxpoints += $points[$counter];
00851                 }
00852                 return $maxpoints;
00853         }
00854         
00863         function &getAvailableAnswers()
00864         {
00865                 $available_answers = array();
00866                 foreach ($this->answers as $answer)
00867                 {
00868                         array_push($available_answers, $answer->getAnswertext());
00869                 }
00870                 return $available_answers;
00871         }
00872 
00885         function isAnswerCorrect($answers, $answer)
00886         {
00887                 $textrating = $this->getTextRating();
00888                 foreach ($answers as $key => $value)
00889                 {
00890                         switch ($textrating)
00891                         {
00892                                 case TEXTGAP_RATING_CASEINSENSITIVE:
00893                                         if (strcmp(strtolower(utf8_decode($value)), strtolower(utf8_decode($answer))) == 0) return $key;
00894                                         break;
00895                                 case TEXTGAP_RATING_CASESENSITIVE:
00896                                         if (strcmp(utf8_decode($value), utf8_decode($answer)) == 0) return $key;
00897                                         break;
00898                                 case TEXTGAP_RATING_LEVENSHTEIN1:
00899                                         if (levenshtein(utf8_decode($value), utf8_decode($answer)) <= 1) return $key;
00900                                         break;
00901                                 case TEXTGAP_RATING_LEVENSHTEIN2:
00902                                         if (levenshtein(utf8_decode($value), utf8_decode($answer)) <= 2) return $key;
00903                                         break;
00904                                 case TEXTGAP_RATING_LEVENSHTEIN3:
00905                                         if (levenshtein(utf8_decode($value), utf8_decode($answer)) <= 3) return $key;
00906                                         break;
00907                                 case TEXTGAP_RATING_LEVENSHTEIN4:
00908                                         if (levenshtein(utf8_decode($value), utf8_decode($answer)) <= 4) return $key;
00909                                         break;
00910                                 case TEXTGAP_RATING_LEVENSHTEIN5:
00911                                         if (levenshtein(utf8_decode($value), utf8_decode($answer)) <= 5) return $key;
00912                                         break;
00913                         }
00914                 }
00915                 return FALSE;
00916         }
00917 
00927         function getTextRating()
00928         {
00929                 return $this->text_rating;
00930         }
00931         
00941         function setTextRating($a_text_rating)
00942         {
00943                 switch ($a_text_rating)
00944                 {
00945                         case TEXTGAP_RATING_CASEINSENSITIVE:
00946                         case TEXTGAP_RATING_CASESENSITIVE:
00947                         case TEXTGAP_RATING_LEVENSHTEIN1:
00948                         case TEXTGAP_RATING_LEVENSHTEIN2:
00949                         case TEXTGAP_RATING_LEVENSHTEIN3:
00950                         case TEXTGAP_RATING_LEVENSHTEIN4:
00951                         case TEXTGAP_RATING_LEVENSHTEIN5:
00952                                 $this->text_rating = $a_text_rating;
00953                                 break;
00954                         default:
00955                                 $this->text_rating = TEXTGAP_RATING_CASEINSENSITIVE;
00956                                 break;
00957                 }
00958         }
00959         
00971         function calculateReachedPoints($active_id, $pass = NULL)
00972         {
00973                 global $ilDB;
00974                 
00975                 $available_answers =& $this->getAvailableAnswers();
00976                 $found_counter = 0;
00977                 
00978                 if (is_null($pass))
00979                 {
00980                         $pass = $this->getSolutionMaxPass($active_id);
00981                 }
00982                 $query = sprintf("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
00983                         $ilDB->quote($active_id . ""),
00984                         $ilDB->quote($this->getId() . ""),
00985                         $ilDB->quote($pass . "")
00986                 );
00987                 $result = $ilDB->query($query);
00988                 $points = 0;
00989                 while ($data = $result->fetchRow(DB_FETCHMODE_ASSOC))
00990                 {
00991                         $enteredtext = $data["value1"];
00992                         $index = $this->isAnswerCorrect($available_answers, $enteredtext);
00993                         if ($index !== FALSE)
00994                         {
00995                                 unset($available_answers[$index]);
00996                                 $points += $this->answers[$index]->getPoints();
00997                         }
00998                 }
00999 
01000                 $points = parent::calculateReachedPoints($active_id, $pass = NULL, $points);
01001                 return $points;
01002         }
01003         
01012         function setCorrectAnswers($a_correct_answers)
01013         {
01014                 $this->correctanswers = $a_correct_answers;
01015         }
01016         
01025         function getCorrectAnswers()
01026         {
01027                 return $this->correctanswers;
01028         }
01029         
01040         function saveWorkingData($active_id, $pass = NULL)
01041         {
01042                 global $ilDB;
01043                 global $ilUser;
01044 
01045                 include_once "./assessment/classes/class.ilObjTest.php";
01046                 $actualpass = ilObjTest::_getPass($active_id);
01047                 $entered_values = 0;
01048                 
01049                 $query = sprintf("DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
01050                         $ilDB->quote($active_id . ""),
01051                         $ilDB->quote($this->getId() . ""),
01052                         $ilDB->quote($actualpass . "")
01053                 );
01054                 $result = $ilDB->query($query);
01055                 foreach ($_POST as $key => $value)
01056                 {
01057                         if (preg_match("/^TEXTSUBSET_(\d+)/", $key, $matches))
01058                         {
01059                                 if (strlen($value))
01060                                 {
01061                                         $query = sprintf("INSERT INTO tst_solutions (solution_id, active_fi, question_fi, value1, value2, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL, %s, NULL)",
01062                                                 $ilDB->quote($active_id),
01063                                                 $ilDB->quote($this->getId()),
01064                                                 $ilDB->quote(trim($value)),
01065                                                 $ilDB->quote($actualpass . "")
01066                                         );
01067                                         $result = $ilDB->query($query);
01068                                         $entered_values++;
01069                                 }
01070                         }
01071                 }
01072                 if ($entered_values)
01073                 {
01074                         include_once ("./classes/class.ilObjAssessmentFolder.php");
01075                         if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01076                         {
01077                                 $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
01078                         }
01079                 }
01080                 else
01081                 {
01082                         include_once ("./classes/class.ilObjAssessmentFolder.php");
01083                         if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01084                         {
01085                                 $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
01086                         }
01087                 }
01088     parent::saveWorkingData($active_id, $pass);
01089                 return true;
01090         }
01091 
01092         function syncWithOriginal()
01093         {
01094                 global $ilDB;
01095                 
01096                 if ($this->original_id)
01097                 {
01098                         $complete = 0;
01099                         if ($this->isComplete())
01100                         {
01101                                 $complete = 1;
01102                         }
01103         
01104                         $estw_time = $this->getEstimatedWorkingTime();
01105                         $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01106         
01107                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, points = %s, working_time=%s, complete = %s WHERE question_id = %s",
01108                                 $ilDB->quote($this->obj_id. ""),
01109                                 $ilDB->quote($this->title. ""),
01110                                 $ilDB->quote($this->comment. ""),
01111                                 $ilDB->quote($this->author. ""),
01112                                 $ilDB->quote($this->question. ""),
01113                                 $ilDB->quote($this->getMaximumPoints() . ""),
01114                                 $ilDB->quote($estw_time. ""),
01115                                 $ilDB->quote($complete. ""),
01116                                 $ilDB->quote($this->original_id. "")
01117                         );
01118                         $result = $ilDB->query($query);
01119                         $query = sprintf("UPDATE qpl_question_textsubset SET textgap_rating = %s, correctanswers = %s WHERE question_fi = %s",
01120                                 $ilDB->quote($this->getTextRating() . ""),
01121                                 $ilDB->quote($this->getCorrectAnswers() . ""),
01122                                 $ilDB->quote($this->original_id . "")
01123                         );
01124                         $result = $ilDB->query($query);
01125 
01126                         if ($result == DB_OK)
01127                         {
01128                                 // Write Ranges to the database
01129                                 
01130                                 // 1. delete old ranges
01131                                 $query = sprintf("DELETE FROM qpl_answer_textsubset WHERE question_fi = %s",
01132                                         $ilDB->quote($this->original_id)
01133                                 );
01134                                 $result = $ilDB->query($query);
01135         
01136                                 // 2. write ranges
01137                                 foreach ($this->answers as $key => $value)
01138                                 {
01139                                         $answer_obj = $this->answers[$key];
01140                                         $query = sprintf("INSERT INTO qpl_answer_textsubset (answer_id, question_fi, answertext, points, aorder) VALUES (NULL, %s, %s, %s, %s)",
01141                                                 $ilDB->quote($this->original_id. ""),
01142                                                 $ilDB->quote($answer_obj->getAnswertext(). ""),
01143                                                 $ilDB->quote($answer_obj->getPoints() . ""),
01144                                                 $ilDB->quote($answer_obj->getOrder() . "")
01145                                         );
01146                                         $answer_result = $ilDB->query($query);
01147                                 }
01148                         }
01149                         parent::syncWithOriginal();
01150                 }
01151         }
01152 
01161         function getQuestionType()
01162         {
01163                 return 10;
01164         }
01165         
01174         function &joinAnswers()
01175         {
01176                 $join = array();
01177                 foreach ($this->answers as $answer)
01178                 {
01179                         if (!is_array($join[$answer->getPoints() . ""]))
01180                         {
01181                                 $join[$answer->getPoints() . ""] = array();
01182                         }
01183                         array_push($join[$answer->getPoints() . ""], $answer->getAnswertext());
01184                 }
01185                 return $join;
01186         }
01187         
01196         function getMaxTextboxWidth()
01197         {
01198                 $maxwidth = 0;
01199                 foreach ($this->answers as $answer)
01200                 {
01201                         $len = strlen($answer->getAnswertext());
01202                         if ($len > $maxwidth) $maxwidth = $len;
01203                 }
01204                 return $maxwidth + 3;
01205         }
01206 
01215         function getAdditionalTableName()
01216         {
01217                 return "qpl_question_textsubset";
01218         }
01219 
01228         function getAnswerTableName()
01229         {
01230                 return "qpl_answer_textsubset";
01231         }
01232 }
01233 
01234 ?>

Generated on Fri Dec 13 2013 13:52:05 for ILIAS Release_3_7_x_branch .rev 46817 by  doxygen 1.7.1