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

assessment/classes/class.assClozeTest.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 
00024 require_once "./assessment/classes/class.assQuestion.php";
00025 require_once "./assessment/classes/class.assAnswerCloze.php";
00026 require_once "./assessment/classes/class.ilQTIUtils.php";
00027 
00028 define("CLOZE_TEXT", "0");
00029 define("CLOZE_SELECT", "1");
00030 define("CLOZE_TEST_IDENTIFIER", "CLOZE QUESTION");
00031 
00042 class ASS_ClozeTest extends ASS_Question
00043 {
00052         var $cloze_text;
00053 
00061         var $gaps;
00062 
00070         var $start_tag;
00071 
00079         var $end_tag;
00092         function ASS_ClozeTest(
00093                 $title = "",
00094                 $comment = "",
00095                 $author = "",
00096                 $owner = -1,
00097                 $cloze_text = ""
00098         )
00099         {
00100                 $this->start_tag = "<gap>";
00101                 $this->end_tag = "</gap>";
00102                 $this->ASS_Question($title, $comment, $author, $owner);
00103                 $this->gaps = array();
00104                 $this->set_cloze_text($cloze_text);
00105         }
00106 
00115         function isComplete()
00116         {
00117                 if (($this->title) and ($this->author) and ($this->cloze_text) and (count($this->gaps)))
00118                 {
00119                         return true;
00120                 }
00121                 else
00122                 {
00123                         return false;
00124                 }
00125         }
00126 
00135         function &createCloseTextArray()
00136         {
00137                 $result = array();
00138                 $search_pattern = "|<gap([^>]*?)>(.*?)</gap>|i";
00139                 preg_match_all($search_pattern, $this->cloze_text, $gaps);
00140                 if (count($gaps[0]))
00141                 {
00142                         // found at least one gap
00143                         $delimiters = preg_split($search_pattern, $this->cloze_text, -1, PREG_SPLIT_OFFSET_CAPTURE);
00144                         $result["gaps"] = array();
00145                         foreach ($gaps[0] as $index => $gap)
00146                         {
00147                                 $result["gaps"][$index] = array();
00148                                 $result["gaps"][$index]["gap"] = $gap;
00149                                 $result["gaps"][$index]["params"] = array();
00150                                 $result["gaps"][$index]["params"]["text"] = $gaps[1][$index];
00151                                 // separate gap params
00152                                 if (preg_match("/name\=\"([^\"]*?)\"/", $gaps[1][$index], $params))
00153                                 {
00154                                         $result["gaps"][$index]["params"]["name"] = $params[1];
00155                                 }
00156                                 else
00157                                 {
00158                                         $result["gaps"][$index]["params"]["name"] = $this->lng->txt("gap") . " " . ($index+1);
00159                                 }
00160                                 if (preg_match("/type\=\"([^\"]*?)\"/", $gaps[1][$index], $params))
00161                                 {
00162                                         $result["gaps"][$index]["params"]["type"] = $params[1];
00163                                 }
00164                                 else
00165                                 {
00166                                         $result["gaps"][$index]["params"]["type"] = "text";
00167                                 }
00168                                 if (preg_match("/shuffle\=\"([^\"]*?)\"/", $gaps[1][$index], $params))
00169                                 {
00170                                         $result["gaps"][$index]["params"]["shuffle"] = $params[1];
00171                                 }
00172                                 else
00173                                 {
00174                                         if (strcmp(strtolower($result["gaps"][$index]["params"]["type"]), "select") == 0)
00175                                         {
00176                                                 $result["gaps"][$index]["params"]["shuffle"] = "yes";
00177                                         }
00178                                 }
00179                                 $result["gaps"][$index]["text"] = array();
00180                                 $result["gaps"][$index]["text"]["text"] = $gaps[2][$index];
00181                                 $textparams = preg_split("/(?<!\\\\),/", $gaps[2][$index]);
00182                                 foreach ($textparams as $key => $value)
00183                                 {
00184                                         $result["gaps"][$index]["text"][$key] = $value;
00185                                 }
00186                         }
00187                         $result["delimiters"] = $delimiters;
00188                 }
00189                 //echo str_replace("\n", "<br />", str_replace(" ", "&nbsp;", ilUtil::prepareFormOutput(print_r($result, true))));
00190                 return $result;         
00191         }
00192 
00201         function createCloseTextFromArray($assoc_array)
00202         {
00203                 $this->cloze_text = "";
00204                 if (count($assoc_array))
00205                 {
00206                         $gap = 0;
00207                         foreach ($assoc_array["delimiters"] as $key => $value)
00208                         {
00209                                 if (($key > 0) && ($key < count($assoc_array["delimiters"])))
00210                                 {
00211                                         if (strcmp($assoc_array["gaps"][$gap]["params"]["shuffle"], "") == 0)
00212                                         {
00213                                                 $shuffle = "";
00214                                         }
00215                                         else
00216                                         {
00217                                                 $shuffle = " shuffle=\"" . $assoc_array["gaps"][$gap]["params"]["shuffle"] . "\"";
00218                                         }
00219                                         if (strlen($assoc_array["gaps"][$gap]["text"]["text"]))
00220                                         {
00221                                                 $textarray = array();
00222                                                 foreach ($assoc_array["gaps"][$gap]["text"] as $textindex => $textvalue)
00223                                                 {
00224                                                         if (preg_match("/\d+/", $textindex))
00225                                                         {
00226                                                                 array_push($textarray, $textvalue);
00227                                                         }
00228                                                 }
00229                                                 $this->cloze_text .= sprintf("<gap name=\"%s\" type=\"%s\"%s>%s</gap>",
00230                                                         $assoc_array["gaps"][$gap]["params"]["name"],
00231                                                         $assoc_array["gaps"][$gap]["params"]["type"],
00232                                                         $shuffle,
00233                                                         join(",", $textarray)
00234                                                 );
00235                                         }
00236                                         $gap++;
00237                                 }
00238                                 $this->cloze_text .= $value[0];
00239                         }
00240                 }
00241         }
00242         
00251         function saveToDb($original_id = "")
00252         {
00253                 global $ilias;
00254 
00255                 $db =& $ilias->db;
00256                 $complete = 0;
00257                 if ($this->isComplete())
00258                 {
00259                         $complete = 1;
00260                 }
00261 
00262                 $estw_time = $this->getEstimatedWorkingTime();
00263                 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00264                 $shuffle = 1;
00265 
00266                 if (!$this->shuffle)
00267                 {
00268                         $shuffle = 0;
00269                 }
00270 
00271                 if ($original_id)
00272                 {
00273                         $original_id = $db->quote($original_id);
00274                 }
00275                 else
00276                 {
00277                         $original_id = "NULL";
00278                 }
00279 
00280                 if ($this->id == -1)
00281                 {
00282                         // Neuen Datensatz schreiben
00283                         $now = getdate();
00284                         $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00285                         $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, working_time, shuffle, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00286                                 $db->quote($this->getQuestionType()),
00287                                 $db->quote($this->obj_id),
00288                                 $db->quote($this->title),
00289                                 $db->quote($this->comment),
00290                                 $db->quote($this->author),
00291                                 $db->quote($this->owner),
00292                                 $db->quote($this->cloze_text),
00293                                 $db->quote($estw_time),
00294                                 $db->quote("$this->shuffle"),
00295                                 $db->quote("$complete"),
00296                                 $db->quote($created),
00297                                 $original_id
00298                         );
00299                         $result = $db->query($query);
00300                         if ($result == DB_OK)
00301                         {
00302                                 $this->id = $this->ilias->db->getLastInsertId();
00303 
00304                                 // create page object of question
00305                                 $this->createPageObject();
00306 
00307                                 // Falls die Frage in einen Test eingef�gt werden soll, auch diese Verbindung erstellen
00308                                 if ($this->getTestId() > 0)
00309                                 {
00310                                         $this->insertIntoTest($this->getTestId());
00311                                 }
00312                         }
00313                 }
00314                 else
00315                 {
00316                         // Vorhandenen Datensatz aktualisieren
00317                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, shuffle = %s, complete = %s WHERE question_id = %s",
00318                                 $db->quote($this->obj_id. ""),
00319                                 $db->quote($this->title),
00320                                 $db->quote($this->comment),
00321                                 $db->quote($this->author),
00322                                 $db->quote($this->cloze_text),
00323                                 $db->quote($estw_time),
00324                                 $db->quote("$this->shuffle"),
00325                                 $db->quote("$complete"),
00326                                 $db->quote($this->id)
00327                                 );
00328                         $result = $db->query($query);
00329                 }
00330 
00331                 if ($result == DB_OK)
00332                 {
00333                         // Antworten schreiben
00334 
00335                         // delete old answers
00336                         $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
00337                                 $db->quote($this->id)
00338                         );
00339                         $result = $db->query($query);
00340                         // Anworten wegschreiben
00341                         foreach ($this->gaps as $key => $value)
00342                         {
00343                                 foreach ($value as $answer_id => $answer_obj)
00344                                 {
00345                                         $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, gap_id, answertext, points, aorder, cloze_type, name, shuffle, correctness, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00346                                                 $db->quote($this->id),
00347                                                 $db->quote($key),
00348                                                 $db->quote($answer_obj->get_answertext() . ""),
00349                                                 $db->quote($answer_obj->get_points() . ""),
00350                                                 $db->quote($answer_obj->get_order() . ""),
00351                                                 $db->quote($answer_obj->get_cloze_type() . ""),
00352                                                 $db->quote($answer_obj->get_name() . ""),
00353                                                 $db->quote($answer_obj->get_shuffle() . ""),
00354                                                 $db->quote($answer_obj->getState() . "")
00355                                                 );
00356                                         $answer_result = $db->query($query);
00357                                 }
00358                         }
00359                 }
00360                 parent::saveToDb($original_id);
00361         }
00362 
00372   function loadFromDb($question_id)
00373   {
00374     global $ilias;
00375     $db =& $ilias->db;
00376 
00377     $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
00378       $db->quote($question_id)
00379     );
00380     $result = $db->query($query);
00381     if (strcmp(strtolower(get_class($result)), db_result) == 0) {
00382       if ($result->numRows() == 1) {
00383         $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00384         $this->id = $question_id;
00385         $this->obj_id = $data->obj_fi;
00386         $this->title = $data->title;
00387         $this->comment = $data->comment;
00388                                 $this->solution_hint = $data->solution_hint;
00389                                 $this->original_id = $data->original_id;
00390         $this->author = $data->author;
00391         $this->owner = $data->owner;
00392         $this->cloze_text = $data->question_text;
00393                                 $this->shuffle = $data->shuffle;
00394         $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00395       }
00396 
00397       $query = sprintf("SELECT * FROM qpl_answers WHERE question_fi = %s ORDER BY gap_id, aorder ASC",
00398         $db->quote($question_id)
00399       );
00400       $result = $db->query($query);
00401       if (strcmp(strtolower(get_class($result)), db_result) == 0) {
00402         $counter = -1;
00403         while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
00404           if ($data->gap_id != $counter) {
00405             $answer_array = array();
00406             array_push($this->gaps, $answer_array);
00407             $counter = $data->gap_id;
00408           }
00409                                         if ($data->cloze_type == CLOZE_SELECT)
00410                                         {
00411                                                 if ($data->correctness == 0)
00412                                                 {
00413                                                         // fix for older single response answers where points could be given for unchecked answers
00414                                                         $data->correctness = 1;
00415                                                         $data->points = 0;
00416                                                 }
00417                                         }
00418           array_push($this->gaps[$counter], new ASS_AnswerCloze($data->answertext, $data->points, $data->aorder, $data->correctness, $data->cloze_type, $data->name, $data->shuffle, $data->answer_id));
00419         }
00420       }
00421     }
00422                 parent::loadFromDb($question_id);
00423   }
00424 
00432         function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00433         {
00434                 if ($this->id <= 0)
00435                 {
00436                         // The question has not been saved. It cannot be duplicated
00437                         return;
00438                 }
00439                 // duplicate the question in database
00440                 $clone = $this;
00441                 $original_id = $this->id;
00442                 if ($original_id <= 0)
00443                 {
00444                         $original_id = "";
00445                 }
00446                 $clone->id = -1;
00447                 if ($title)
00448                 {
00449                         $clone->setTitle($title);
00450                 }
00451                 if ($author)
00452                 {
00453                         $clone->setAuthor($author);
00454                 }
00455                 if ($owner)
00456                 {
00457                         $clone->setOwner($owner);
00458                 }
00459                 if ($for_test)
00460                 {
00461                         $clone->saveToDb($original_id);
00462                 }
00463                 else
00464                 {
00465                         $clone->saveToDb();
00466                 }
00467 
00468                 // copy question page content
00469                 $clone->copyPageOfQuestion($original_id);
00470 
00471                 return $clone->id;
00472         }
00473         
00483         function from_xml($xml_text)
00484         {
00485                 $result = false;
00486                 if (!empty($this->domxml))
00487                 {
00488                         $this->domxml->free();
00489                 }
00490                 $xml_text = preg_replace("/>\s*?</", "><", $xml_text);
00491                 $this->domxml = domxml_open_mem($xml_text);
00492                 if (!empty($this->domxml))
00493                 {
00494                         $root = $this->domxml->document_element();
00495                         $item = $root->first_child();
00496                         $this->setTitle($item->get_attribute("title"));
00497                         $this->gaps = array();
00498                         $itemnodes = $item->child_nodes();
00499                         $materials = array();
00500                         $gapcounter = 0;
00501                         foreach ($itemnodes as $index => $node)
00502                         {
00503                                 switch ($node->node_name())
00504                                 {
00505                                         case "qticomment":
00506                                                 $comment = $node->get_content();
00507                                                 if (strpos($comment, "ILIAS Version=") !== false)
00508                                                 {
00509                                                 }
00510                                                 elseif (strpos($comment, "Questiontype=") !== false)
00511                                                 {
00512                                                 }
00513                                                 elseif (strpos($comment, "Author=") !== false)
00514                                                 {
00515                                                         $comment = str_replace("Author=", "", $comment);
00516                                                         $this->setAuthor($comment);
00517                                                 }
00518                                                 else
00519                                                 {
00520                                                         $this->setComment($comment);
00521                                                 }
00522                                                 break;
00523                                         case "duration":
00524                                                 $iso8601period = $node->get_content();
00525                                                 if (preg_match("/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches))
00526                                                 {
00527                                                         $this->setEstimatedWorkingTime($matches[4], $matches[5], $matches[6]);
00528                                                 }
00529                                                 break;
00530                                         case "presentation":
00531                                                 $flow = $node->first_child();
00532                                                 $flownodes = $flow->child_nodes();
00533                                                 foreach ($flownodes as $idx => $flownode)
00534                                                 {
00535                                                         if (strcmp($flownode->node_name(), "material") == 0)
00536                                                         {
00537                                                                 $mattext = $flownode->first_child();
00538                                                                 array_push($materials, $mattext->get_content());
00539                                                         }
00540                                                         elseif (strcmp($flownode->node_name(), "response_str") == 0)
00541                                                         {
00542                                                                 $ident = $flownode->get_attribute("ident");
00543                                                                 $this->gaps["$ident"] = array();
00544                                                                 $shuffle = "";
00545                                                                 $subnodes = $flownode->child_nodes();
00546                                                                 foreach ($subnodes as $node_type)
00547                                                                 {
00548                                                                         switch ($node_type->node_name())
00549                                                                         {
00550                                                                                 case "render_choice":
00551                                                                                         $render_type = $node_type;
00552                                                                                         if (strcmp($render_type->node_name(), "render_choice") == 0)
00553                                                                                         {
00554                                                                                                 // select gap
00555                                                                                                 $shuffle = $render_type->get_attribute("shuffle");
00556                                                                                                 $labels = $render_type->child_nodes();
00557                                                                                                 foreach ($labels as $lidx => $response_label)
00558                                                                                                 {
00559                                                                                                         $material = $response_label->first_child();
00560                                                                                                         $mattext = $material->first_child();
00561                                                                                                         $shuf = 0;
00562                                                                                                         if (strcmp(strtolower($shuffle), "yes") == 0)
00563                                                                                                         {
00564                                                                                                                 $shuf = 1;
00565                                                                                                         }
00566                                                                                                         array_push($this->gaps["$ident"], new ASS_AnswerCloze($mattext->get_content(), 0, count($this->gaps["$ident"]), 0, CLOZE_SELECT, $ident, $shuf));
00567                                                                                                 }
00568                                                                                         }
00569                                                                                         break;
00570                                                                                 case "render_fib":
00571                                                                                         break;
00572                                                                                 case "material":
00573                                                                                         $matlabel = $node_type->get_attribute("label");
00574                                                                                         if (strcmp($matlabel, "suggested_solution") == 0)
00575                                                                                         {
00576                                                                                                 $mattype = $node_type->first_child();
00577                                                                                                 if (strcmp($mattype->node_name(), "mattext") == 0)
00578                                                                                                 {
00579                                                                                                         $suggested_solution = $mattype->get_content();
00580                                                                                                         if ($suggested_solution)
00581                                                                                                         {
00582                                                                                                                 if ($this->getId() < 1)
00583                                                                                                                 {
00584                                                                                                                         $this->saveToDb();
00585                                                                                                                 }
00586                                                                                                                 if (preg_match("/gap_(\d+)/", $ident, $matches))
00587                                                                                                                 {
00588                                                                                                                         $this->setSuggestedSolution($suggested_solution, $matches[1], true);
00589                                                                                                                 }
00590                                                                                                         }
00591                                                                                                 }
00592                                                                                         }
00593                                                                                         break;
00594                                                                         }
00595                                                                 }
00596                                                         }
00597                                                 }
00598                                                 break;
00599                                         case "resprocessing":
00600                                                 $resproc_nodes = $node->child_nodes();
00601                                                 foreach ($resproc_nodes as $index => $respcondition)
00602                                                 {
00603                                                         if (strcmp($respcondition->node_name(), "respcondition") == 0)
00604                                                         {
00605                                                                 $respcondition_array =& ilQTIUtils::_getRespcondition($respcondition);
00606                                                                 $found_answer = 0;
00607                                                                 foreach ($this->gaps[$respcondition_array["conditionvar"]["respident"]] as $key => $value)
00608                                                                 {
00609                                                                         if (strcmp($value->get_answertext(), $respcondition_array["conditionvar"]["value"]) == 0)
00610                                                                         {
00611                                                                                 $found_answer = 1;
00612                                                                                 $this->gaps[$respcondition_array["conditionvar"]["respident"]][$key]->set_points($respcondition_array["setvar"]["points"]);
00613                                                                                 if ($respcondition_array["conditionvar"]["selected"])
00614                                                                                 {
00615                                                                                         $this->gaps[$respcondition_array["conditionvar"]["respident"]][$key]->setChecked();
00616                                                                                 }
00617                                                                         }
00618                                                                 }
00619                                                                 if (!$found_answer)
00620                                                                 {
00621                                                                         // text gap
00622                                                                         array_push($this->gaps[$respcondition_array["conditionvar"]["respident"]], new ASS_AnswerCloze($respcondition_array["conditionvar"]["value"], $respcondition_array["setvar"]["points"], count($this->gaps[$respcondition_array["conditionvar"]["respident"]]), 1, CLOZE_TEXT, $respcondition_array["conditionvar"]["respident"], 0));
00623                                                                 }
00624                                                         }
00625                                                 }
00626                                                 break;
00627                                 }
00628                         }
00629                         $this->gaps = array_values($this->gaps);
00630                         $i = 0;
00631                         foreach ($materials as $key => $value)
00632                         {
00633                                 $this->cloze_text .= $value;
00634                                 $gaptext = $this->get_gap_text_list($i);
00635                                 if ($gaptext)
00636                                 {
00637                                         $type = " type=\"select\"";
00638                                         if ($this->gaps[$i][0]->get_cloze_type() == CLOZE_TEXT)
00639                                         {
00640                                                 $type = " type=\"text\"";
00641                                         }
00642                                         $shuffle = " shuffle=\"yes\"";
00643                                         if (!$this->gaps[$i][0]->get_shuffle())
00644                                         {
00645                                                 $shuffle = " shuffle=\"no\"";
00646                                         }
00647                                         $this->cloze_text .= "<gap$type$shuffle>$gaptext</gap>";
00648                                 }
00649                                 $i++;
00650                         }
00651                         $result = true;
00652                 }
00653                 return $result;
00654         }
00655 
00665         function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false)
00666         {
00667                 if (!empty($this->domxml))
00668                 {
00669                         $this->domxml->free();
00670                 }
00671                 $xml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<questestinterop></questestinterop>\n";
00672                 $this->domxml = domxml_open_mem($xml_header);
00673                 $root = $this->domxml->document_element();
00674                 // qti ident
00675                 $qtiIdent = $this->domxml->create_element("item");
00676                 $qtiIdent->set_attribute("ident", "il_".IL_INST_ID."_qst_".$this->getId());
00677                 $qtiIdent->set_attribute("title", $this->getTitle());
00678                 $root->append_child($qtiIdent);
00679                 // add qti comment
00680                 $qtiComment = $this->domxml->create_element("qticomment");
00681                 $qtiCommentText = $this->domxml->create_text_node($this->getComment());
00682                 $qtiComment->append_child($qtiCommentText);
00683                 $qtiIdent->append_child($qtiComment);
00684                 $qtiComment = $this->domxml->create_element("qticomment");
00685                 $qtiCommentText = $this->domxml->create_text_node("ILIAS Version=".$this->ilias->getSetting("ilias_version"));
00686                 $qtiComment->append_child($qtiCommentText);
00687                 $qtiIdent->append_child($qtiComment);
00688                 $qtiComment = $this->domxml->create_element("qticomment");
00689                 $qtiCommentText = $this->domxml->create_text_node("Questiontype=".CLOZE_TEST_IDENTIFIER);
00690                 $qtiComment->append_child($qtiCommentText);
00691                 $qtiIdent->append_child($qtiComment);
00692                 $qtiComment = $this->domxml->create_element("qticomment");
00693                 $qtiCommentText = $this->domxml->create_text_node("Author=".$this->getAuthor());
00694                 $qtiComment->append_child($qtiCommentText);
00695                 $qtiIdent->append_child($qtiComment);
00696                 // add estimated working time
00697                 $qtiDuration = $this->domxml->create_element("duration");
00698                 $workingtime = $this->getEstimatedWorkingTime();
00699                 $qtiDurationText = $this->domxml->create_text_node(sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]));
00700                 $qtiDuration->append_child($qtiDurationText);
00701                 $qtiIdent->append_child($qtiDuration);
00702                 // PART I: qti presentation
00703                 $qtiPresentation = $this->domxml->create_element("presentation");
00704                 $qtiPresentation->set_attribute("label", $this->getTitle());
00705                 // add flow to presentation
00706                 $qtiFlow = $this->domxml->create_element("flow");
00707 
00708                 $text_parts = preg_split("/<gap.*?<\/gap>/", $this->get_cloze_text());
00709                 // add material with question text to presentation
00710                 for ($i = 0; $i <= $this->get_gap_count(); $i++)
00711                 {
00712                         // n-th text part
00713                         $qtiMaterial = $this->domxml->create_element("material");
00714                         $qtiMatText = $this->domxml->create_element("mattext");
00715                         $qtiMatTextText = $this->domxml->create_text_node($text_parts[$i]);
00716                         $qtiMatText->append_child($qtiMatTextText);
00717                         $qtiMaterial->append_child($qtiMatText);
00718                         $qtiFlow->append_child($qtiMaterial);
00719 
00720                         if ($i < $this->get_gap_count())
00721                         {
00722                                 // add gap
00723                                 $gap = $this->get_gap($i);
00724                                 if ($gap[0]->get_cloze_type() == CLOZE_SELECT)
00725                                 {
00726                                         // comboboxes
00727                                         $qtiResponseStr = $this->domxml->create_element("response_str");
00728                                         $qtiResponseStr->set_attribute("ident", "gap_$i");
00729                                         $qtiResponseStr->set_attribute("rcardinality", "Single");
00730                                         $solution = $this->getSuggestedSolution($i);
00731                                         if (count($solution))
00732                                         {
00733                                                 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00734                                                 {
00735                                                         $qtiMaterial = $this->domxml->create_element("material");
00736                                                         $qtiMaterial->set_attribute("label", "suggested_solution");
00737                                                         $qtiMatText = $this->domxml->create_element("mattext");
00738                                                         $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00739                                                         if (strcmp($matches[1], "") != 0)
00740                                                         {
00741                                                                 $intlink = $solution["internal_link"];
00742                                                         }
00743                                                         $qtiMatTextText = $this->domxml->create_text_node($intlink);
00744                                                         $qtiMatText->append_child($qtiMatTextText);
00745                                                         $qtiMaterial->append_child($qtiMatText);
00746                                                         $qtiResponseStr->append_child($qtiMaterial);
00747                                                 }
00748                                         }
00749                                         
00750                                         $qtiRenderChoice = $this->domxml->create_element("render_choice");
00751                                         // shuffle output
00752                                         if ($gap[0]->get_shuffle())
00753                                         {
00754                                                 $qtiRenderChoice->set_attribute("shuffle", "Yes");
00755                                         }
00756                                         else
00757                                         {
00758                                                 $qtiRenderChoice->set_attribute("shuffle", "No");
00759                                         }
00760 
00761                                         $gkeys = array_keys($gap);
00762                                         if ($this->getshuffle() && $a_shuffle)
00763                                         {
00764                                                 $gkeys = $this->pcArrayShuffle($gkeys);
00765                                         }
00766 
00767                                         // add answers
00768                                         foreach ($gkeys as $key)
00769                                         {
00770                                                 $value = $gap[$key];
00771                                                 $qtiResponseLabel = $this->domxml->create_element("response_label");
00772                                                 $qtiResponseLabel->set_attribute("ident", $key);
00773                                                 $qtiMaterial = $this->domxml->create_element("material");
00774                                                 $qtiMatText = $this->domxml->create_element("mattext");
00775                                                 $tmpvalue = $value->get_answertext();
00776                                                 $qtiMatTextText = $this->domxml->create_text_node($tmpvalue);
00777                                                 $qtiMatText->append_child($qtiMatTextText);
00778                                                 $qtiMaterial->append_child($qtiMatText);
00779                                                 $qtiResponseLabel->append_child($qtiMaterial);
00780                                                 $qtiRenderChoice->append_child($qtiResponseLabel);
00781                                         }
00782                                         $qtiResponseStr->append_child($qtiRenderChoice);
00783                                         $qtiFlow->append_child($qtiResponseStr);
00784                                 }
00785                                 else
00786                                 {
00787                                         // text fields
00788                                         $qtiResponseStr = $this->domxml->create_element("response_str");
00789                                         $qtiResponseStr->set_attribute("ident", "gap_$i");
00790                                         $qtiResponseStr->set_attribute("rcardinality", "Single");
00791                                         $solution = $this->getSuggestedSolution($i);
00792                                         if (count($solution))
00793                                         {
00794                                                 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00795                                                 {
00796                                                         $qtiMaterial = $this->domxml->create_element("material");
00797                                                         $qtiMaterial->set_attribute("label", "suggested_solution");
00798                                                         $qtiMatText = $this->domxml->create_element("mattext");
00799                                                         $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00800                                                         if (strcmp($matches[1], "") != 0)
00801                                                         {
00802                                                                 $intlink = $solution["internal_link"];
00803                                                         }
00804                                                         $qtiMatTextText = $this->domxml->create_text_node($intlink);
00805                                                         $qtiMatText->append_child($qtiMatTextText);
00806                                                         $qtiMaterial->append_child($qtiMatText);
00807                                                         $qtiResponseStr->append_child($qtiMaterial);
00808                                                 }
00809                                         }
00810                                         $qtiRenderFib = $this->domxml->create_element("render_fib");
00811                                         $qtiRenderFib->set_attribute("fibtype", "String");
00812                                         $qtiRenderFib->set_attribute("prompt", "Box");
00813                                         $qtiResponseLabel = $this->domxml->create_element("response_label");
00814                                         $qtiResponseLabel->set_attribute("ident", $i);
00815                                         $qtiRenderFib->append_child($qtiResponseLabel);
00816                                         $qtiResponseStr->append_child($qtiRenderFib);
00817                                         $qtiFlow->append_child($qtiResponseStr);
00818                                 }
00819                         }
00820                 }
00821                 $qtiPresentation->append_child($qtiFlow);
00822                 $qtiIdent->append_child($qtiPresentation);
00823 
00824                 // PART II: qti resprocessing
00825                 $qtiResprocessing = $this->domxml->create_element("resprocessing");
00826                 $qtiOutcomes = $this->domxml->create_element("outcomes");
00827                 $qtiDecvar = $this->domxml->create_element("decvar");
00828                 $qtiOutcomes->append_child($qtiDecvar);
00829                 $qtiResprocessing->append_child($qtiOutcomes);
00830                 // add response conditions
00831                 for ($i = 0; $i < $this->get_gap_count(); $i++)
00832                 {
00833                         $gap = $this->get_gap($i);
00834                         if ($gap[0]->get_cloze_type() == CLOZE_SELECT)
00835                         {
00836                                 foreach ($gap as $index => $answer)
00837                                 {
00838                                         $qtiRespcondition = $this->domxml->create_element("respcondition");
00839                                         $qtiRespcondition->set_attribute("continue", "Yes");
00840                                         // qti conditionvar
00841                                         $qtiConditionvar = $this->domxml->create_element("conditionvar");
00842 
00843                                         if (!$answer->isStateSet())
00844                                         {
00845                                                 $qtinot = $this->domxml->create_element("not");
00846                                         }
00847                                         
00848                                         $qtiVarequal = $this->domxml->create_element("varequal");
00849                                         $qtiVarequal->set_attribute("respident", "gap_$i");
00850                                         $qtiVarequalText = $this->domxml->create_text_node($answer->get_answertext());
00851                                         $qtiVarequal->append_child($qtiVarequalText);
00852                                         if (!$answer->isStateSet())
00853                                         {
00854                                                 $qtiConditionvar->append_child($qtinot);
00855                                                 $qtinot->append_child($qtiVarequal);
00856                                         }
00857                                         else
00858                                         {
00859                                                 $qtiConditionvar->append_child($qtiVarequal);
00860                                         }
00861                                         // qti setvar
00862                                         $qtiSetvar = $this->domxml->create_element("setvar");
00863                                         $qtiSetvar->set_attribute("action", "Add");
00864                                         $qtiSetvarText = $this->domxml->create_text_node($answer->get_points());
00865                                         $qtiSetvar->append_child($qtiSetvarText);
00866                                         // qti displayfeedback
00867                                         $qtiDisplayfeedback = $this->domxml->create_element("displayfeedback");
00868                                         $qtiDisplayfeedback->set_attribute("feedbacktype", "Response");
00869                                         $linkrefid = "";
00870                                         if ($answer->isStateSet())
00871                                         {
00872                                                 $linkrefid = "$i" . "_True";
00873                                         }
00874                                                 else
00875                                         {
00876                                                 $linkrefid = "$i" . "_False_$index";
00877                                         }
00878                                         $qtiDisplayfeedback->set_attribute("linkrefid", $linkrefid);
00879                                         $qtiRespcondition->append_child($qtiConditionvar);
00880                                         $qtiRespcondition->append_child($qtiSetvar);
00881                                         $qtiRespcondition->append_child($qtiDisplayfeedback);
00882                                         $qtiResprocessing->append_child($qtiRespcondition);
00883                                 }
00884                         }
00885                         else
00886                         {
00887                                 foreach ($gap as $index => $answer)
00888                                 {
00889                                         $qtiRespcondition = $this->domxml->create_element("respcondition");
00890                                         $qtiRespcondition->set_attribute("continue", "Yes");
00891                                         // qti conditionvar
00892                                         $qtiConditionvar = $this->domxml->create_element("conditionvar");
00893                                         $qtiVarequal = $this->domxml->create_element("varequal");
00894                                         $qtiVarequal->set_attribute("respident", "gap_$i");
00895                                         $qtiVarequalText = $this->domxml->create_text_node($answer->get_answertext());
00896                                         $qtiVarequal->append_child($qtiVarequalText);
00897                                         $qtiConditionvar->append_child($qtiVarequal);
00898                                         // qti setvar
00899                                         $qtiSetvar = $this->domxml->create_element("setvar");
00900                                         $qtiSetvar->set_attribute("action", "Add");
00901                                         $qtiSetvarText = $this->domxml->create_text_node($answer->get_points());
00902                                         $qtiSetvar->append_child($qtiSetvarText);
00903                                         // qti displayfeedback
00904                                         $qtiDisplayfeedback = $this->domxml->create_element("displayfeedback");
00905                                         $qtiDisplayfeedback->set_attribute("feedbacktype", "Response");
00906                                         $qtiDisplayfeedback->set_attribute("linkrefid", "$i" . "_True_$index");
00907                                         $qtiRespcondition->append_child($qtiConditionvar);
00908                                         $qtiRespcondition->append_child($qtiSetvar);
00909                                         $qtiRespcondition->append_child($qtiDisplayfeedback);
00910                                         $qtiResprocessing->append_child($qtiRespcondition);
00911                                 }
00912                         }
00913                 }
00914                 $qtiIdent->append_child($qtiResprocessing);
00915 
00916                 // PART III: qti itemfeedback
00917                 for ($i = 0; $i < $this->get_gap_count(); $i++)
00918                 {
00919                         $gap = $this->get_gap($i);
00920                         if ($gap[0]->get_cloze_type() == CLOZE_SELECT)
00921                         {
00922                                 foreach ($gap as $index => $answer)
00923                                 {
00924                                         $qtiItemfeedback = $this->domxml->create_element("itemfeedback");
00925                                         $linkrefid = "";
00926                                         if ($answer->isStateSet())
00927                                         {
00928                                                 $linkrefid = "$i" . "_True";
00929                                         }
00930                                                 else
00931                                         {
00932                                                 $linkrefid = "$i" . "_False_$index";
00933                                         }
00934                                         $qtiItemfeedback->set_attribute("ident", $linkrefid);
00935                                         $qtiItemfeedback->set_attribute("view", "All");
00936                                         // qti flow_mat
00937                                         $qtiFlowmat = $this->domxml->create_element("flow_mat");
00938                                         $qtiMaterial = $this->domxml->create_element("material");
00939                                         $qtiMattext = $this->domxml->create_element("mattext");
00940                                         // Insert response text for right/wrong answers here!!!
00941                                         $qtiMattextText = $this->domxml->create_text_node("");
00942                                         $qtiMattext->append_child($qtiMattextText);
00943                                         $qtiMaterial->append_child($qtiMattext);
00944                                         $qtiFlowmat->append_child($qtiMaterial);
00945                                         $qtiItemfeedback->append_child($qtiFlowmat);
00946                                         $qtiIdent->append_child($qtiItemfeedback);
00947                                 }
00948                         }
00949                         else
00950                         {
00951                                 foreach ($gap as $index => $answer)
00952                                 {
00953                                         $qtiItemfeedback = $this->domxml->create_element("itemfeedback");
00954                                         $linkrefid = "";
00955                                         if ($answer->isStateSet())
00956                                         {
00957                                                 $linkrefid = "$i" . "_True_$index";
00958                                         }
00959                                                 else
00960                                         {
00961                                                 $linkrefid = "$i" . "_False_$index";
00962                                         }
00963                                         $qtiItemfeedback->set_attribute("ident", $linkrefid);
00964                                         $qtiItemfeedback->set_attribute("view", "All");
00965                                         // qti flow_mat
00966                                         $qtiFlowmat = $this->domxml->create_element("flow_mat");
00967                                         $qtiMaterial = $this->domxml->create_element("material");
00968                                         $qtiMattext = $this->domxml->create_element("mattext");
00969                                         // Insert response text for right/wrong answers here!!!
00970                                         $qtiMattextText = $this->domxml->create_text_node("");
00971                                         $qtiMattext->append_child($qtiMattextText);
00972                                         $qtiMaterial->append_child($qtiMattext);
00973                                         $qtiFlowmat->append_child($qtiMaterial);
00974                                         $qtiItemfeedback->append_child($qtiFlowmat);
00975                                         $qtiIdent->append_child($qtiItemfeedback);
00976                                 }
00977                         }
00978                 }
00979 
00980                 $xml = $this->domxml->dump_mem(true);
00981                 if (!$a_include_header)
00982                 {
00983                         $pos = strpos($xml, "?>");
00984                         $xml = substr($xml, $pos + 2);
00985                 }
00986 //echo htmlentities($xml);
00987                 return $xml;
00988 
00989         }
00990 
01002         function set_cloze_text($cloze_text = "")
01003         {
01004                 $this->gaps = array();
01005                 $this->cloze_text =& $cloze_text;
01006                 $close = $this->createCloseTextArray();
01007                 if (count($close))
01008                 {
01009                         foreach ($close["gaps"] as $key => $value)
01010                         {
01011                                 if (strcmp(strtolower($value["params"]["type"]), "select") == 0)
01012                                 {
01013                                         $type = CLOZE_SELECT;
01014                                 }
01015                                         else
01016                                 {
01017                                         $type = CLOZE_TEXT;
01018                                 }
01019                                 if ($type == CLOZE_TEXT)
01020                                 {
01021                                         $default_state = 1;
01022                                 }
01023                                 else
01024                                 {
01025                                         $default_state = 0;
01026                                 }
01027                                 $name = $value["params"]["name"];
01028                                 if (strcmp(strtolower($value["params"]["shuffle"]), "no") == 0)
01029                                 {
01030                                         $shuffle = 0;
01031                                 }
01032                                         else
01033                                 {
01034                                         $shuffle = 1;
01035                                 }
01036                                 $answer_array = array();
01037                                 foreach ($value["text"] as $index => $textvalue)
01038                                 {
01039                                         if (preg_match("/\d+/", $index))
01040                                         {
01041                                                 $textvalue = str_replace("\,", ",", $textvalue);
01042                                                 array_push($answer_array, new ASS_AnswerCloze($textvalue, 0, $index, $default_state, $type, $name, $shuffle));
01043                                         }
01044                                 }
01045                                 array_push($this->gaps, $answer_array);
01046                         }
01047                 }
01048         }
01049 
01059   function get_cloze_text() {
01060     return $this->cloze_text;
01061   }
01062 
01072   function get_start_tag() {
01073     return $this->start_tag;
01074   }
01075 
01085   function get_end_tag() {
01086     return $this->end_tag;
01087   }
01088 
01098   function set_start_tag($start_tag = "<gap>") {
01099     $this->start_tag = $start_tag;
01100   }
01101 
01102 
01112   function set_end_tag($end_tag = "</gap>") {
01113     $this->end_tag = $end_tag;
01114   }
01115 
01124   function rebuild_cloze_text() 
01125         {
01126                 $close =& $this->createCloseTextArray();
01127                 if (count($close))
01128                 {
01129                         for ($i = 0; $i < count($this->gaps); $i++)
01130                         {
01131                                 $gaptext = $this->get_gap_text_list($i);
01132                                 $textparams = preg_split("/(?<!\\\\),/", $gaptext);
01133                                 $close["gaps"][$i]["text"] = array();
01134                                 $close["gaps"][$i]["text"]["text"] = $gaptext;
01135                                 foreach ($textparams as $key => $value)
01136                                 {
01137                                         $close["gaps"][$i]["text"][$key] = $value;
01138                                 }
01139                         }
01140                 }
01141                 $this->createCloseTextFromArray($close);
01142   }
01143 
01155   function get_gap($index = 0) {
01156     if ($index < 0) return array();
01157     if (count($this->gaps) < 1) return array();
01158     if ($index >= count($this->gaps)) return array();
01159     return $this->gaps[$index];
01160   }
01161 
01171   function get_gap_count() {
01172     return count($this->gaps);
01173   }
01174 
01187   function get_gap_text_list($index = 0, $separator = ",") {
01188     if ($index < 0) return "";
01189     if (count($this->gaps) < 1) return "";
01190     if ($index >= count($this->gaps)) return "";
01191     $result = array();
01192     foreach ($this->gaps[$index] as $key => $value) {
01193                         array_push($result, str_replace(",", "\,", $value->get_answertext()));
01194     }
01195     return join($separator, $result);
01196   }
01206   function get_gap_text_count($index = 0) {
01207     if ($index < 0) return 0;
01208     if (count($this->gaps) < 1) return 0;
01209     if ($index >= count($this->gaps)) return 0;
01210     return count($this->gaps[$index]);
01211   }
01222   function delete_gap($index = 0) {
01223     if ($index < 0) return;
01224     if (count($this->gaps) < 1) return;
01225     if ($index >= count($this->gaps)) return;
01226                 $close = $this->createCloseTextArray();
01227                 unset($close["gaps"][$index]);
01228                 $this->createCloseTextFromArray($close);
01229     unset($this->gaps[$index]);
01230     $this->gaps = array_values($this->gaps);
01231   }
01232 
01241   function flush_gaps() {
01242     $this->gaps = array();
01243   }
01244 
01256   function delete_answertext_by_index($gap_index = 0, $answertext_index = 0) {
01257     if ($gap_index < 0) return;
01258     if (count($this->gaps) < 1) return;
01259     if ($gap_index >= count($this->gaps)) return;
01260     $old_text = $this->get_gap_text_list($gap_index);
01261                 if (count($this->gaps[$gap_index]) == 1) {
01262                         $this->delete_gap($gap_index);
01263                 } else {
01264                         $close = $this->createCloseTextArray();
01265                         unset($this->gaps[$gap_index][$answertext_index]);
01266       $this->gaps[$gap_index] = array_values($this->gaps[$gap_index]);
01267                         unset($close["gaps"][$gap_index]["text"][$answertext_index]);
01268                         $this->createCloseTextFromArray($close);
01269                 }
01270   }
01271 
01284   function set_answertext($index = 0, $answertext_index = 0, $answertext = "", $add_gaptext=0) {
01285                 $answertext = str_replace("\,", ",", $answertext);
01286         if ($add_gaptext == 1)    {
01287         $arr = $this->gaps[$index][0];
01288         if (strlen($this->gaps[$index][count($this->gaps[$index])-1]->get_answertext()) != 0) {
01289                                 $default_state = 0;
01290                                 if ($arr->get_cloze_type() == CLOZE_TEXT)
01291                                 {
01292                                         $default_state = 1;
01293                                 }
01294                 array_push($this->gaps[$index], new ASS_AnswerCloze($answertext, 0, count($this->gaps[$index]),
01295                         $default_state, $arr->get_cloze_type(),
01296                         $arr->get_name(), $arr->get_shuffle()));
01297                 $this->rebuild_cloze_text();
01298         }
01299         return;
01300     }
01301     if ($index < 0) return;
01302     if (count($this->gaps) < 1) return;
01303     if ($index >= count($this->gaps)) return;
01304     if ($answertext_index < 0) return;
01305     if (count($this->gaps[$index]) < 1) return;
01306     if ($answertext_index >= count($this->gaps[$index])) return;
01307 
01308 
01309     if (strlen($answertext) == 0) {
01310       // delete the answertext
01311       $this->delete_answertext($index, $this->gaps[$index][$answertext_index]->get_answertext());
01312     } else {
01313       $this->gaps[$index][$answertext_index]->set_answertext($answertext);
01314       $this->rebuild_cloze_text();
01315     }
01316   }
01317 
01326         function update_all_gap_params() {
01327                 global $lng;
01328                 $close = $this->createCloseTextArray();
01329                 for ($i = 0; $i < $this->get_gap_count(); $i++)
01330                 {
01331                         $gaptext = $this->get_gap_text_list($i);
01332                         if ($this->gaps[$i][0]->get_cloze_type() == CLOZE_TEXT)
01333                         {
01334                                 $close["gaps"][$i]["params"]["type"] = "text";
01335                                 if (array_key_exists("shuffle", $close["gaps"][$i]["params"]))
01336                                 {
01337                                         unset($close["gaps"][$i]["params"]["shuffle"]);
01338                                 }
01339                         }
01340                                 else
01341                         {
01342                                 $close["gaps"][$i]["params"]["type"] = "select";
01343                                 if ($this->gaps[$i][0]->get_shuffle() == 0)
01344                                 {
01345                                         $close["gaps"][$i]["params"]["shuffle"] = "no";
01346                                 }
01347                                         else
01348                                 {
01349                                         $close["gaps"][$i]["params"]["shuffle"] = "yes";
01350                                 }
01351                         }
01352                         $name = $this->gaps[$i][0]->get_name();
01353                         if (!$name)
01354                         {
01355                                 $name = $this->lng->txt("gap") . " " . ($i+1);
01356                         }
01357                         $close["gaps"][$i]["params"]["name"] = $name;
01358                 }
01359                 $this->createCloseTextFromArray($close);
01360         }
01361 
01372         function set_cloze_type($index, $cloze_type = CLOZE_TEXT) {
01373     if ($index < 0) return;
01374     if (count($this->gaps) < 1) return;
01375     if ($index >= count($this->gaps)) return;
01376                 $close = $this->createCloseTextArray();
01377                 foreach ($this->gaps[$index] as $key => $value) {
01378                         $this->gaps[$index][$key]->set_cloze_type($cloze_type);
01379                         $this->gaps[$index][$key]->setState(1);
01380                 }
01381                 if ($cloze_type == CLOZE_TEXT)
01382                 {
01383                         $type = "text";
01384                 }
01385                 else
01386                 {
01387                         $type = "select";
01388                 }
01389                 $close["gaps"][$index]["type"] = $type;
01390                 $this->createCloseTextFromArray($close);
01391         }
01392 
01404   function set_gap_points($index = 0, $points = 0.0) {
01405     if ($index < 0) return;
01406     if (count($this->gaps) < 1) return;
01407     if ($index >= count($this->gaps)) return;
01408     foreach ($this->gaps[$index] as $key => $value) {
01409       $this->gaps[$index][$key]->set_points($points);
01410     }
01411   }
01412 
01424   function set_gap_shuffle($index = 0, $shuffle = 1) {
01425     if ($index < 0) return;
01426     if (count($this->gaps) < 1) return;
01427     if ($index >= count($this->gaps)) return;
01428     foreach ($this->gaps[$index] as $key => $value) {
01429       $this->gaps[$index][$key]->set_shuffle($shuffle);
01430     }
01431   }
01432 
01433 
01446   function set_single_answer_points($index_gaps = 0, $index_answerobject = 0, $points = 0.0) {
01447     if ($index_gaps < 0) return;
01448     if (count($this->gaps) < 1) return;
01449     if ($index_gaps >= count($this->gaps)) return;
01450     if ($index_answerobject < 0) return;
01451     if (count($this->gaps[$index_gaps]) < 1) return;
01452     if ($index_answerobject >= count($this->gaps[$index_gaps])) return;
01453     $this->gaps[$index_gaps][$index_answerobject]->set_points($points);
01454   }
01455 
01468   function set_single_answer_state($index_gaps = 0, $index_answerobject = 0, $state = 0) {
01469     if ($index_gaps < 0) return;
01470     if (count($this->gaps) < 1) return;
01471     if ($index_gaps >= count($this->gaps)) return;
01472     if ($index_answerobject < 0) return;
01473     if (count($this->gaps[$index_gaps]) < 1) return;
01474     if ($index_answerobject >= count($this->gaps[$index_gaps])) return;
01475     $this->gaps[$index_gaps][$index_answerobject]->setState($state);
01476   }
01477         
01487   function getReachedPoints($user_id, $test_id) {
01488     $found_value1 = array();
01489     $found_value2 = array();
01490     $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01491       $this->ilias->db->quote($user_id),
01492       $this->ilias->db->quote($test_id),
01493       $this->ilias->db->quote($this->getId())
01494     );
01495     $result = $this->ilias->db->query($query);
01496                 $user_result = array();
01497     while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
01498                         if (strcmp($data->value2, "") != 0)
01499                         {
01500                                 $user_result[$data->value1] = array(
01501                                         "gap_id" => $data->value1,
01502                                         "value" => $data->value2
01503                                 );
01504                         }
01505     }
01506     $points = 0;
01507     $counter = 0;
01508                 foreach ($user_result as $gap_id => $value) {
01509                         if ($this->gaps[$gap_id][0]->get_cloze_type() == CLOZE_TEXT) 
01510                         {
01511                                 $foundsolution = 0;
01512                                 foreach ($this->gaps[$gap_id] as $k => $v) {
01513                                         if ((strcmp(strtolower($v->get_answertext()), strtolower($value["value"])) == 0) && (!$foundsolution)) {
01514                                                 $points += $v->get_points();
01515                                                 $foundsolution = 1;
01516                                         }
01517                                 }
01518                         } 
01519                         else 
01520                         {
01521                                 if ($value["value"] >= 0)
01522                                 {
01523                                         foreach ($this->gaps[$gap_id] as $answerkey => $answer)
01524                                         {
01525                                                 if ($value["value"] == $answerkey)
01526                                                 {
01527                                                         $points += $answer->get_points();
01528                                                 }
01529                                         }
01530                                 }
01531                         }
01532     }
01533     return $points;
01534   }
01535 
01545   function getReachedInformation($user_id, $test_id) {
01546     $found_value1 = array();
01547     $found_value2 = array();
01548     $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01549       $this->ilias->db->quote($user_id),
01550       $this->ilias->db->quote($test_id),
01551       $this->ilias->db->quote($this->getId())
01552     );
01553     $result = $this->ilias->db->query($query);
01554     while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
01555       array_push($found_value1, $data->value1);
01556       array_push($found_value2, $data->value2);
01557     }
01558     $counter = 1;
01559                 $user_result = array();
01560     foreach ($found_value1 as $key => $value) {
01561       if ($this->gaps[$value][0]->get_cloze_type() == CLOZE_TEXT) 
01562                         {
01563                                 $solution = array(
01564                                         "gap" => "$counter",
01565                                         "points" => 0,
01566                                         "true" => 0,
01567                                         "value" => $found_value2[$key]
01568                                 );
01569         foreach ($this->gaps[$value] as $k => $v) {
01570           if (strcmp(strtolower($v->get_answertext()), strtolower($found_value2[$key])) == 0) {
01571                                                 $solution = array(
01572                                                         "gap" => "$counter",
01573                                                         "points" => $v->get_points(),
01574                                                         "true" => 1,
01575                                                         "value" => $found_value2[$key]
01576                                                 );
01577           }
01578         }
01579       } 
01580                         else 
01581                         {
01582                                 $solution = array(
01583                                         "gap" => "$counter",
01584                                         "points" => 0,
01585                                         "true" => 0,
01586                                         "value" => $found_value2[$key]
01587                                 );
01588         if ($this->gaps[$value][$found_value1[$key]]->isStateSet()) {
01589                                         $solution["points"] = $this->gaps[$value][$found_value1[$key]]->get_points();
01590                                         $solution["true"] = 1;
01591         }
01592       }
01593                         $counter++;
01594                         $user_result[$value] = $solution;
01595     }
01596     return $user_result;
01597   }
01598 
01607   function getMaximumPoints() {
01608     $points = 0;
01609     foreach ($this->gaps as $key => $value) {
01610       if ($value[0]->get_cloze_type() == CLOZE_TEXT) {
01611         $points += $value[0]->get_points();
01612       } else {
01613                                 $points_arr = array("set" => 0, "unset" => 0);
01614         foreach ($value as $key2 => $value2) {
01615                                         if ($value2->get_points() > $points_arr["set"])
01616                                         {
01617                                                 $points_arr["set"] = $value2->get_points();
01618                                         }
01619                                 }
01620                                 $points += $points_arr["set"];
01621       }
01622     }
01623     return $points;
01624   }
01625 
01636   function saveWorkingData($test_id, $limit_to = LIMIT_NO_LIMIT) {
01637     global $ilDB;
01638                 global $ilUser;
01639     $db =& $ilDB->db;
01640 
01641     $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01642       $db->quote($ilUser->id),
01643       $db->quote($test_id),
01644       $db->quote($this->getId())
01645     );
01646     $result = $db->query($query);
01647 
01648     foreach ($_POST as $key => $value) {
01649       if (preg_match("/^gap_(\d+)/", $key, $matches)) {
01650         $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
01651                                         $db->quote($ilUser->id),
01652                                         $db->quote($test_id),
01653           $db->quote($this->getId()),
01654           $db->quote($matches[1]),
01655           $db->quote(ilUtil::stripSlashes($value))
01656         );
01657         $result = $db->query($query);
01658       }
01659     }
01660     //parent::saveWorkingData($limit_to);
01661                 return true;
01662   }
01663 
01664         function syncWithOriginal()
01665         {
01666                 global $ilias;
01667                 if ($this->original_id)
01668                 {
01669                         $complete = 0;
01670                         if ($this->isComplete())
01671                         {
01672                                 $complete = 1;
01673                         }
01674                         $db = & $ilias->db;
01675         
01676                         $estw_time = $this->getEstimatedWorkingTime();
01677                         $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01678         
01679                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, shuffle = %s, complete = %s WHERE question_id = %s",
01680                                 $db->quote($this->obj_id. ""),
01681                                 $db->quote($this->title . ""),
01682                                 $db->quote($this->comment . ""),
01683                                 $db->quote($this->author . ""),
01684                                 $db->quote($this->cloze_text . ""),
01685                                 $db->quote($estw_time . ""),
01686                                 $db->quote($this->shuffle . ""),
01687                                 $db->quote($complete . ""),
01688                                 $db->quote($this->original_id . "")
01689                                 );
01690                         $result = $db->query($query);
01691 
01692                         if ($result == DB_OK)
01693                         {
01694                                 // write answers
01695                                 // delete old answers
01696                                 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
01697                                         $db->quote($this->original_id)
01698                                 );
01699                                 $result = $db->query($query);
01700         
01701                                 foreach ($this->gaps as $key => $value)
01702                                 {
01703                                         foreach ($value as $answer_id => $answer_obj)
01704                                         {
01705                                                 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, gap_id, answertext, points, aorder, cloze_type, name, shuffle, correctness, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
01706                                                         $db->quote($this->original_id . ""),
01707                                                         $db->quote($key . ""),
01708                                                         $db->quote($answer_obj->get_answertext() . ""),
01709                                                         $db->quote($answer_obj->get_points() . ""),
01710                                                         $db->quote($answer_obj->get_order() . ""),
01711                                                         $db->quote($answer_obj->get_cloze_type() . ""),
01712                                                         $db->quote($answer_obj->get_name() . ""),
01713                                                         $db->quote($answer_obj->get_shuffle() . ""),
01714                                                         $db->quote($answer_obj->getState() . "")
01715                                                         );
01716                                                 $answer_result = $db->query($query);
01717                                         }
01718                                 }
01719                         }
01720                         parent::syncWithOriginal();
01721                 }
01722         }
01723 
01732         function getQuestionType()
01733         {
01734                 return 3;
01735         }
01736 }
01737 
01738 ?>

Generated on Fri Dec 13 2013 08:00:13 for ILIAS Release_3_3_x_branch .rev 46803 by  doxygen 1.7.1