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

assessment/classes/class.assImagemapQuestion.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.assAnswerImagemap.php";
00026 
00027 define ("IMAGEMAP_QUESTION_IDENTIFIER", "IMAGE MAP QUESTION");
00028 
00039 class ASS_ImagemapQuestion extends ASS_Question {
00040 
00048   var $question;
00049 
00057   var $answers;
00058 
00066   var $imagemap_filename;
00067 
00075   var $image_filename;
00076 
00084   var $imagemap_contents;
00085         var $coords;
00086 
00101   function ASS_ImagemapQuestion(
00102     $title = "",
00103     $comment = "",
00104     $author = "",
00105     $owner = -1,
00106     $question = "",
00107     $imagemap_filename = "",
00108     $image_filename = ""
00109 
00110   )
00111   {
00112     $this->ASS_Question($title, $comment, $author, $owner);
00113     $this->question = $question;
00114     $this->imagemap_filename = $imagemap_filename;
00115     $this->image_filename = $image_filename;
00116     $this->answers = array();
00117                 $this->coords = array();
00118   }
00119 
00128         function isComplete()
00129         {
00130                 if (($this->title) and ($this->author) and ($this->question) and ($this->image_filename) and (count($this->answers)))
00131                 {
00132                         return true;
00133                 }
00134                         else
00135                 {
00136                         return false;
00137                 }
00138         }
00139 
00148         function saveToDb($original_id = "")
00149         {
00150                 global $ilias;
00151 
00152                 $complete = 0;
00153                 if ($this->isComplete())
00154                 {
00155                         $complete = 1;
00156                 }
00157 
00158                 $db = & $ilias->db;
00159 
00160                 $estw_time = $this->getEstimatedWorkingTime();
00161                 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00162                 if ($original_id)
00163                 {
00164                         $original_id = $db->quote($original_id);
00165                 }
00166                 else
00167                 {
00168                         $original_id = "NULL";
00169                 }
00170 
00171                 if ($this->id == -1)
00172                 {
00173                         // Neuen Datensatz schreiben
00174                         $now = getdate();
00175                         $question_type = $this->getQuestionType();
00176                         $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00177                         $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, working_time, points, image_file, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00178                                 $db->quote($question_type),
00179                                 $db->quote($this->obj_id),
00180                                 $db->quote($this->title),
00181                                 $db->quote($this->comment),
00182                                 $db->quote($this->author),
00183                                 $db->quote($this->owner),
00184                                 $db->quote($this->question),
00185                                 $db->quote($estw_time),
00186                                 $db->quote($this->getMaximumPoints() . ""),
00187                                 $db->quote($this->image_filename),
00188                                 $db->quote("$complete"),
00189                                 $db->quote($created),
00190                                 $original_id
00191                         );
00192                         $result = $db->query($query);
00193                         if ($result == DB_OK)
00194                         {
00195                                 $this->id = $db->getLastInsertId();
00196 
00197                                 // create page object of question
00198                                 $this->createPageObject();
00199 
00200                                 // Falls die Frage in einen Test eingef�gt werden soll, auch diese Verbindung erstellen
00201                                 if ($this->getTestId() > 0)
00202                                 {
00203                                         $this->insertIntoTest($this->getTestId());
00204                                 }
00205                         }
00206                 }
00207                 else
00208                 {
00209                         // Vorhandenen Datensatz aktualisieren
00210                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, points = %s, image_file = %s, complete = %s WHERE question_id = %s",
00211                                 $db->quote($this->obj_id. ""),
00212                                 $db->quote($this->title),
00213                                 $db->quote($this->comment),
00214                                 $db->quote($this->author),
00215                                 $db->quote($this->question),
00216                                 $db->quote($estw_time),
00217                                 $db->quote($this->getMaximumPoints() . ""),
00218                                 $db->quote($this->image_filename),
00219                                 $db->quote("$complete"),
00220                                 $db->quote($this->id)
00221                         );
00222                         $result = $db->query($query);
00223                 }
00224 
00225                 if ($result == DB_OK)
00226                 {
00227                         $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
00228                                 $db->quote($this->id)
00229                         );
00230                         $result = $db->query($query);
00231                         // Anworten wegschreiben
00232                         foreach ($this->answers as $key => $value)
00233                         {
00234                                 $answer_obj = $this->answers[$key];
00235                                 //print "id:".$this->id." answer tex:".$answer_obj->get_answertext()." answer_obj->get_order():".$answer_obj->get_order()." answer_obj->get_coords():".$answer_obj->get_coords()." answer_obj->get_area():".$answer_obj->get_area();
00236                                 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, correctness, coords, area, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, NULL)",
00237                                         $db->quote($this->id),
00238                                         $db->quote($answer_obj->get_answertext() . ""),
00239                                         $db->quote($answer_obj->get_points() . ""),
00240                                         $db->quote($answer_obj->get_order() . ""),
00241                                         $db->quote($answer_obj->getState() . ""),
00242                                         $db->quote($answer_obj->get_coords() . ""),
00243                                         $db->quote($answer_obj->get_area() . "")
00244                                         );
00245                                 $answer_result = $db->query($query);
00246                                 }
00247                 }
00248                 parent::saveToDb($original_id);
00249         }
00250 
00258         function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00259         {
00260                 if ($this->id <= 0)
00261                 {
00262                         // The question has not been saved. It cannot be duplicated
00263                         return;
00264                 }
00265                 // duplicate the question in database
00266                 $clone = $this;
00267                 include_once ("./assessment/classes/class.assQuestion.php");
00268                 $original_id = ASS_Question::_getOriginalId($this->id);
00269                 $clone->id = -1;
00270                 if ($title)
00271                 {
00272                         $clone->setTitle($title);
00273                 }
00274                 if ($author)
00275                 {
00276                         $clone->setAuthor($author);
00277                 }
00278                 if ($owner)
00279                 {
00280                         $clone->setOwner($owner);
00281                 }
00282                 if ($for_test)
00283                 {
00284                         $clone->saveToDb($original_id);
00285                 }
00286                 else
00287                 {
00288                         $clone->saveToDb();
00289                 }
00290 
00291                 // copy question page content
00292                 $clone->copyPageOfQuestion($original_id);
00293 
00294                 // duplicate the image
00295                 $clone->duplicateImage($original_id);
00296                 return $clone->id;
00297         }
00298 
00299         function duplicateImage($question_id)
00300         {
00301                 $imagepath = $this->getImagePath();
00302                 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00303                 if (!file_exists($imagepath)) {
00304                         ilUtil::makeDirParents($imagepath);
00305                 }
00306                 $filename = $this->get_image_filename();
00307                 if (!copy($imagepath_original . $filename, $imagepath . $filename)) {
00308                         print "image could not be duplicated!!!! ";
00309                 }
00310         }
00311 
00321   function loadFromDb($question_id)
00322   {
00323     global $ilias;
00324 
00325     $db = & $ilias->db;
00326     $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
00327       $db->quote($question_id)
00328     );
00329     $result = $db->query($query);
00330     if (strcmp(strtolower(get_class($result)), db_result) == 0) {
00331       if ($result->numRows() == 1) {
00332         $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00333         $this->id = $question_id;
00334                                 $this->obj_id = $data->obj_fi;
00335         $this->title = $data->title;
00336         $this->comment = $data->comment;
00337         $this->author = $data->author;
00338                                 $this->original_id = $data->original_id;
00339                                 $this->solution_hint = $data->solution_hint;
00340         $this->owner = $data->owner;
00341         $this->question = $data->question_text;
00342         $this->image_filename = $data->image_file;
00343         $this->points = $data->points;
00344         $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00345       }
00346       $query = sprintf("SELECT * FROM qpl_answers WHERE question_fi = %s ORDER BY aorder ASC",
00347         $db->quote($question_id)
00348       );
00349       $result = $db->query($query);
00350       if (strcmp(strtolower(get_class($result)), db_result) == 0) {
00351         while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
00352                                         if ($data->correctness == 0)
00353                                         {
00354                                                 // fix for older single response answers where points could be given for unchecked answers
00355                                                 $data->correctness = 1;
00356                                                 $data->points = 0;
00357                                         }
00358           array_push($this->answers, new ASS_AnswerImagemap($data->answertext, $data->points, $data->aorder, $data->correctness, $data->coords, $data->area));
00359         }
00360       }
00361     }
00362                 parent::loadFromDb($question_id);
00363   }
00364 
00372         function addAnswer($answertext, $points, $answerorder, $correctness, $coords, $area)
00373         {
00374                 array_push($this->answers, new ASS_AnswerImagemap($answertext, $points, $answerorder, $correctness, $coords, $area));
00375         }
00376         
00386         function from_xml($xml_text)
00387         {
00388                 $result = false;
00389                 if (!empty($this->domxml))
00390                 {
00391                         $this->domxml->free();
00392                 }
00393                 $xml_text = preg_replace("/>\s*?</", "><", $xml_text);
00394                 $this->domxml = domxml_open_mem($xml_text);
00395                 if (!empty($this->domxml))
00396                 {
00397                         $root = $this->domxml->document_element();
00398                         $item = $root->first_child();
00399                         $this->setTitle($item->get_attribute("title"));
00400                         $this->gaps = array();
00401                         $itemnodes = $item->child_nodes();
00402                         $materials = array();
00403                         $filename = "";
00404                         $image = "";
00405                         $shuffle = "";
00406                         foreach ($itemnodes as $index => $node)
00407                         {
00408                                 switch ($node->node_name())
00409                                 {
00410                                         case "qticomment":
00411                                                 $comment = $node->node_value();
00412                                                 if (strpos($comment, "ILIAS Version=") !== false)
00413                                                 {
00414                                                 }
00415                                                 elseif (strpos($comment, "Questiontype=") !== false)
00416                                                 {
00417                                                 }
00418                                                 elseif (strpos($comment, "Author=") !== false)
00419                                                 {
00420                                                         $comment = str_replace("Author=", "", $comment);
00421                                                         $this->setAuthor($comment);
00422                                                 }
00423                                                 else
00424                                                 {
00425                                                         $this->setComment($comment);
00426                                                 }
00427                                                 break;
00428                                         case "itemmetadata":
00429                                                 $md_array = array();
00430                                                 $metanodes = $node->child_nodes();
00431                                                 foreach ($metanodes as $metanode)
00432                                                 {
00433                                                         switch ($metanode->node_name())
00434                                                         {
00435                                                                 case "qtimetadata":
00436                                                                         $metafields = $metanode->child_nodes();
00437                                                                         foreach ($metafields as $metafield)
00438                                                                         {
00439                                                                                 switch ($metafield->node_name())
00440                                                                                 {
00441                                                                                         case "qtimetadatafield":
00442                                                                                                 $metafieldlist = $metafield->child_nodes();
00443                                                                                                 $md = array("label" => "", "entry" => "");
00444                                                                                                 foreach ($metafieldlist as $attr)
00445                                                                                                 {
00446                                                                                                         switch ($attr->node_name())
00447                                                                                                         {
00448                                                                                                                 case "fieldlabel":
00449                                                                                                                         $md["label"] = $attr->get_content();
00450                                                                                                                         break;
00451                                                                                                                 case "fieldentry":
00452                                                                                                                         $md["entry"] = $attr->get_content();
00453                                                                                                                         break;
00454                                                                                                         }
00455                                                                                                 }
00456                                                                                                 array_push($md_array, $md);
00457                                                                                                 break;
00458                                                                                 }
00459                                                                         }
00460                                                                         break;
00461                                                         }
00462                                                 }
00463                                                 foreach ($md_array as $md)
00464                                                 {
00465                                                         switch ($md["label"])
00466                                                         {
00467                                                                 case "ILIAS_VERSION":
00468                                                                         break;
00469                                                                 case "QUESTIONTYPE":
00470                                                                         break;
00471                                                                 case "AUTHOR":
00472                                                                         $this->setAuthor($md["entry"]);
00473                                                                         break;
00474                                                         }
00475                                                 }
00476                                                 break;
00477                                         case "duration":
00478                                                 $iso8601period = $node->node_value();
00479                                                 if (preg_match("/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches))
00480                                                 {
00481                                                         $this->setEstimatedWorkingTime($matches[4], $matches[5], $matches[6]);
00482                                                 }
00483                                                 break;
00484                                         case "presentation":
00485                                                 $flow = $node->first_child();
00486                                                 $flownodes = $flow->child_nodes();
00487                                                 foreach ($flownodes as $idx => $flownode)
00488                                                 {
00489                                                         if (strcmp($flownode->node_name(), "material") == 0)
00490                                                         {
00491                                                                 $mattext = $flownode->first_child();
00492                                                                 $this->set_question($mattext->node_value());
00493                                                         }
00494                                                         elseif (strcmp($flownode->node_name(), "response_xy") == 0)
00495                                                         {
00496                                                                 $ident = $flownode->get_attribute("ident");
00497                                                                 $subnodes = $flownode->child_nodes();
00498                                                                 foreach ($subnodes as $node_type)
00499                                                                 {
00500                                                                         switch ($node_type->node_name())
00501                                                                         {
00502                                                                                 case "material":
00503                                                                                         $matlabel = $node_type->get_attribute("label");
00504                                                                                         if (strcmp($matlabel, "suggested_solution") == 0)
00505                                                                                         {
00506                                                                                                 $mattype = $node_type->first_child();
00507                                                                                                 if (strcmp($mattype->node_name(), "mattext") == 0)
00508                                                                                                 {
00509                                                                                                         $suggested_solution = $mattype->node_value();
00510                                                                                                         if ($suggested_solution)
00511                                                                                                         {
00512                                                                                                                 if ($this->getId() < 1)
00513                                                                                                                 {
00514                                                                                                                         $this->saveToDb();
00515                                                                                                                 }
00516                                                                                                                 $this->setSuggestedSolution($suggested_solution, 0, true);
00517                                                                                                         }
00518                                                                                                 }
00519                                                                                         }
00520                                                                                         break;
00521                                                                                 case "render_hotspot":
00522                                                                                         $render_hotspot = $node_type;
00523                                                                                         $labels = $render_hotspot->child_nodes();
00524                                                                                         foreach ($labels as $lidx => $response_label)
00525                                                                                         {
00526                                                                                                 if (strcmp($response_label->node_name(), "material") == 0)
00527                                                                                                 {
00528                                                                                                         // image map image
00529                                                                                                         $mattype = $response_label->first_child();
00530                                                                                                         if (strcmp($mattype->node_name(), "matimage") == 0)
00531                                                                                                         {
00532                                                                                                                 $filename = $mattype->get_attribute("label");
00533                                                                                                                 $image = base64_decode($mattype->node_value());
00534                                                                                                         }
00535                                                                                                 }
00536                                                                                                 else
00537                                                                                                 {
00538                                                                                                         $matident = $response_label->get_attribute("ident");
00539                                                                                                         switch ($response_label->get_attribute("rarea"))
00540                                                                                                         {
00541                                                                                                                 case "Ellipse":
00542                                                                                                                         $materials[$matident]["area"] = "circle";
00543                                                                                                                         break;
00544                                                                                                                 case "Bounded":
00545                                                                                                                         $materials[$matident]["area"] = "poly";
00546                                                                                                                         break;
00547                                                                                                                 case "Rectangle":
00548                                                                                                                         $materials[$matident]["area"] = "rect";
00549                                                                                                                         break;
00550                                                                                                         }
00551                                                                                                         $material_children = $response_label->child_nodes();
00552                                                                                                         foreach ($material_children as $midx => $childnode)
00553                                                                                                         {
00554                                                                                                                 if (strcmp($childnode->node_name(), "#text") == 0)
00555                                                                                                                 {
00556                                                                                                                         $materials[$matident]["coords"] = $childnode->node_value();
00557                                                                                                                 }
00558                                                                                                                 elseif (strcmp($childnode->node_name(), "material") == 0)
00559                                                                                                                 {
00560                                                                                                                         $materials[$matident]["answertext"] = $childnode->node_value();
00561                                                                                                                 }
00562                                                                                                         }
00563                                                                                                 }
00564                                                                                         }
00565                                                                                         break;
00566                                                                         }
00567                                                                 }
00568                                                         }
00569                                                 }
00570                                                 break;
00571                                         case "resprocessing":
00572                                                 $resproc_nodes = $node->child_nodes();
00573                                                 foreach ($resproc_nodes as $index => $respcondition)
00574                                                 {
00575                                                         if (strcmp($respcondition->node_name(), "respcondition") == 0)
00576                                                         {
00577                                                                 $respcondition_array =& ilQTIUtils::_getRespcondition($respcondition);
00578                                                                 foreach ($materials as $index => $material)
00579                                                                 {
00580                                                                         if (strcmp($material["coords"], $respcondition_array["conditionvar"]["value"]) == 0)
00581                                                                         {
00582                                                                                 $this->add_answer(
00583                                                                                         $material["answertext"], 
00584                                                                                         $respcondition_array["setvar"]["points"],
00585                                                                                         $respcondition_array["conditionvar"]["selected"],
00586                                                                                         $index,
00587                                                                                         $material["coords"],
00588                                                                                         $material["area"]
00589                                                                                 );
00590                                                                         }
00591                                                                 }
00592                                                         }
00593                                                 }
00594                                                 break;
00595                                 }
00596                         }
00597                         if ($filename)
00598                         {
00599                                 $this->saveToDb();
00600                                 $imagepath = $this->getImagePath();
00601                                 if (!file_exists($imagepath))
00602                                 {
00603                                         ilUtil::makeDirParents($imagepath);
00604                                 }
00605                                 $imagepath .=  $filename;
00606                                 $fh = fopen($imagepath, "wb");
00607                                 if ($fh == false)
00608                                 {
00609                                         global $ilErr;
00610                                         $ilErr->raiseError($this->lng->txt("error_save_image_file") . ": $php_errormsg", $ilErr->MESSAGE);
00611                                         return;
00612                                 }
00613                                 $imagefile = fwrite($fh, $image);
00614                                 fclose($fh);
00615                                 $this->image_filename = $filename;
00616                         }
00617                         $result = true;
00618                 }
00619                 return $result;
00620         }
00621 
00631         function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false)
00632         {
00633                 if (!empty($this->domxml))
00634                 {
00635                         $this->domxml->free();
00636                 }
00637                 $xml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<questestinterop></questestinterop>\n";
00638                 $this->domxml = domxml_open_mem($xml_header);
00639                 $root = $this->domxml->document_element();
00640                 // qti ident
00641                 $qtiIdent = $this->domxml->create_element("item");
00642                 $qtiIdent->set_attribute("ident", "il_".IL_INST_ID."_qst_".$this->getId());
00643                 $qtiIdent->set_attribute("title", $this->getTitle());
00644                 $root->append_child($qtiIdent);
00645         // add question description
00646                 $qtiComment = $this->domxml->create_element("qticomment");
00647                 $qtiCommentText = $this->domxml->create_text_node($this->getComment());
00648                 $qtiComment->append_child($qtiCommentText);
00649                 $qtiIdent->append_child($qtiComment);
00650         // add estimated working time
00651                 $qtiDuration = $this->domxml->create_element("duration");
00652                 $workingtime = $this->getEstimatedWorkingTime();
00653                 $qtiDurationText = $this->domxml->create_text_node(sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]));
00654                 $qtiDuration->append_child($qtiDurationText);
00655                 $qtiIdent->append_child($qtiDuration);
00656                 // add ILIAS specific metadata
00657                 $qtiItemmetadata = $this->domxml->create_element("itemmetadata");
00658                 $qtiMetadata = $this->domxml->create_element("qtimetadata");
00659                 
00660                 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00661                 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00662                 $qtiFieldlabelText = $this->domxml->create_text_node("ILIAS_VERSION");
00663                 $qtiFieldlabel->append_child($qtiFieldlabelText);
00664                 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00665                 $qtiFieldentryText = $this->domxml->create_text_node($this->ilias->getSetting("ilias_version"));
00666                 $qtiFieldentry->append_child($qtiFieldentryText);
00667                 $qtiMetadatafield->append_child($qtiFieldlabel);
00668                 $qtiMetadatafield->append_child($qtiFieldentry);
00669                 $qtiMetadata->append_child($qtiMetadatafield);
00670 
00671                 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00672                 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00673                 $qtiFieldlabelText = $this->domxml->create_text_node("QUESTIONTYPE");
00674                 $qtiFieldlabel->append_child($qtiFieldlabelText);
00675                 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00676                 $qtiFieldentryText = $this->domxml->create_text_node(IMAGEMAP_QUESTION_IDENTIFIER);
00677                 $qtiFieldentry->append_child($qtiFieldentryText);
00678                 $qtiMetadatafield->append_child($qtiFieldlabel);
00679                 $qtiMetadatafield->append_child($qtiFieldentry);
00680                 $qtiMetadata->append_child($qtiMetadatafield);
00681                 
00682                 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00683                 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00684                 $qtiFieldlabelText = $this->domxml->create_text_node("AUTHOR");
00685                 $qtiFieldlabel->append_child($qtiFieldlabelText);
00686                 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00687                 $qtiFieldentryText = $this->domxml->create_text_node($this->getAuthor());
00688                 $qtiFieldentry->append_child($qtiFieldentryText);
00689                 $qtiMetadatafield->append_child($qtiFieldlabel);
00690                 $qtiMetadatafield->append_child($qtiFieldentry);
00691                 $qtiMetadata->append_child($qtiMetadatafield);
00692                 
00693                 $qtiItemmetadata->append_child($qtiMetadata);
00694                 $qtiIdent->append_child($qtiItemmetadata);
00695                 
00696                 // PART I: qti presentation
00697                 $qtiPresentation = $this->domxml->create_element("presentation");
00698                 $qtiPresentation->set_attribute("label", $this->getTitle());
00699                 // add flow to presentation
00700                 $qtiFlow = $this->domxml->create_element("flow");
00701                 // add material with question text to presentation
00702                 $qtiMaterial = $this->domxml->create_element("material");
00703                 $qtiMatText = $this->domxml->create_element("mattext");
00704                 $qtiMatTextText = $this->domxml->create_text_node($this->get_question());
00705                 $qtiMatText->append_child($qtiMatTextText);
00706                 $qtiMaterial->append_child($qtiMatText);
00707                 $qtiFlow->append_child($qtiMaterial);
00708                 // add answers to presentation
00709                 $qtiResponseXy = $this->domxml->create_element("response_xy");
00710                 $qtiResponseXy->set_attribute("ident", "IM");
00711                 $qtiResponseXy->set_attribute("rcardinality", "Single");
00712                 $solution = $this->getSuggestedSolution(0);
00713                 if (count($solution))
00714                 {
00715                         if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00716                         {
00717                                 $qtiMaterial = $this->domxml->create_element("material");
00718                                 $qtiMaterial->set_attribute("label", "suggested_solution");
00719                                 $qtiMatText = $this->domxml->create_element("mattext");
00720                                 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00721                                 if (strcmp($matches[1], "") != 0)
00722                                 {
00723                                         $intlink = $solution["internal_link"];
00724                                 }
00725                                 $qtiMatTextText = $this->domxml->create_text_node($intlink);
00726                                 $qtiMatText->append_child($qtiMatTextText);
00727                                 $qtiMaterial->append_child($qtiMatText);
00728                                 $qtiResponseXy->append_child($qtiMaterial);
00729                         }
00730                 }
00731                 $qtiRenderHotspot = $this->domxml->create_element("render_hotspot");
00732                 $qtiMaterial = $this->domxml->create_element("material");
00733                 $qtiMatImage = $this->domxml->create_element("matimage");
00734                 $imagetype = "image/jpeg";
00735                 if (preg_match("/.*\.(png|gif)$/", $this->get_image_filename(), $matches))
00736                 {
00737                         $imagetype = "image/" . $matches[1];
00738                 }
00739                 $qtiMatImage->set_attribute("imagtype", $imagetype);
00740                 $qtiMatImage->set_attribute("label", $this->get_image_filename());
00741                 if ($a_include_binary)
00742                 {
00743                         if ($test_output)
00744                         {
00745                                 $qtiMatImage->set_attribute("uri", $this->getImagePathWeb() . $this->get_image_filename());
00746                         }
00747                         else
00748                         {
00749                                 $qtiMatImage->set_attribute("embedded", "base64");
00750                                 $imagepath = $this->getImagePath() . $this->get_image_filename();
00751                                 $fh = fopen($imagepath, "rb");
00752                                 if ($fh == false)
00753                                 {
00754                                         global $ilErr;
00755                                         $ilErr->raiseError($this->lng->txt("error_open_image_file"), $ilErr->MESSAGE);
00756                                         return;
00757                                 }
00758                                 $imagefile = fread($fh, filesize($imagepath));
00759                                 fclose($fh);
00760                                 $base64 = base64_encode($imagefile);
00761                                 $qtiBase64Data = $this->domxml->create_text_node($base64);
00762                                 $qtiMatImage->append_child($qtiBase64Data);
00763                         }
00764                 }
00765                 $qtiMaterial->append_child($qtiMatImage);
00766                 $qtiRenderHotspot->append_child($qtiMaterial);
00767                 // add answers
00768                 foreach ($this->answers as $index => $answer)
00769                 {
00770                         $qtiResponseLabel = $this->domxml->create_element("response_label");
00771                         $qtiResponseLabel->set_attribute("ident", $index);
00772                         switch ($answer->get_area())
00773                         {
00774                                 case "rect":
00775                                         $qtiResponseLabel->set_attribute("rarea", "Rectangle");
00776                                         break;
00777                                 case "circle":
00778                                         $qtiResponseLabel->set_attribute("rarea", "Ellipse");
00779                                         break;
00780                                 case "poly":
00781                                         $qtiResponseLabel->set_attribute("rarea", "Bounded");
00782                                         break;
00783                         }
00784                         $qtiResponseLabelCoords = $this->domxml->create_text_node($answer->get_coords());
00785                         $qtiMaterial = $this->domxml->create_element("material");
00786                         $qtiMatText = $this->domxml->create_element("mattext");
00787                         $qtiMatTextText = $this->domxml->create_text_node($answer->get_answertext());
00788                         $qtiMatText->append_child($qtiMatTextText);
00789                         $qtiMaterial->append_child($qtiMatText);
00790                         $qtiResponseLabel->append_child($qtiResponseLabelCoords);
00791                         $qtiResponseLabel->append_child($qtiMaterial);
00792                         $qtiRenderHotspot->append_child($qtiResponseLabel);
00793                 }
00794                 $qtiResponseXy->append_child($qtiRenderHotspot);
00795                 $qtiFlow->append_child($qtiResponseXy);
00796                 $qtiPresentation->append_child($qtiFlow);
00797                 $qtiIdent->append_child($qtiPresentation);
00798 
00799                 // PART II: qti resprocessing
00800                 $qtiResprocessing = $this->domxml->create_element("resprocessing");
00801                 $qtiOutcomes = $this->domxml->create_element("outcomes");
00802                 $qtiDecvar = $this->domxml->create_element("decvar");
00803                 $qtiOutcomes->append_child($qtiDecvar);
00804                 $qtiResprocessing->append_child($qtiOutcomes);
00805                 // add response conditions
00806                 foreach ($this->answers as $index => $answer)
00807                 {
00808                         $qtiRespcondition = $this->domxml->create_element("respcondition");
00809                         $qtiRespcondition->set_attribute("continue", "Yes");
00810                         // qti conditionvar
00811                         $qtiConditionvar = $this->domxml->create_element("conditionvar");
00812                         if (!$answer->isStateSet())
00813                         {
00814                                 $qtinot = $this->domxml->create_element("not");
00815                         }
00816                         $qtiVarinside = $this->domxml->create_element("varinside");
00817                         $qtiVarinside->set_attribute("respident", "IM");
00818                         switch ($answer->get_area())
00819                         {
00820                                 case "rect":
00821                                         $qtiVarinside->set_attribute("areatype", "Rectangle");
00822                                         break;
00823                                 case "circle":
00824                                         $qtiVarinside->set_attribute("areatype", "Ellipse");
00825                                         break;
00826                                 case "poly":
00827                                         $qtiVarinside->set_attribute("areatype", "Bounded");
00828                                         break;
00829                         }
00830                         $qtiVarinsideText = $this->domxml->create_text_node($answer->get_coords());
00831                         $qtiVarinside->append_child($qtiVarinsideText);
00832                         if (!$answer->isStateSet())
00833                         {
00834                                 $qtiConditionvar->append_child($qtinot);
00835                                 $qtinot->append_child($qtiVarinside);
00836                         }
00837                         else
00838                         {
00839                                 $qtiConditionvar->append_child($qtiVarinside);
00840                         }
00841                         // qti setvar
00842                         $qtiSetvar = $this->domxml->create_element("setvar");
00843                         $qtiSetvar->set_attribute("action", "Add");
00844                         $qtiSetvarText = $this->domxml->create_text_node($answer->get_points());
00845                         $qtiSetvar->append_child($qtiSetvarText);
00846                         // qti displayfeedback
00847                         $qtiDisplayfeedback = $this->domxml->create_element("displayfeedback");
00848                         $qtiDisplayfeedback->set_attribute("feedbacktype", "Response");
00849                         $linkrefid = "";
00850                         if ($answer->isStateSet())
00851                         {
00852                                 $linkrefid = "True";
00853                         }
00854                           else
00855                         {
00856                                 $linkrefid = "False_$index";
00857                         }
00858                         $qtiDisplayfeedback->set_attribute("linkrefid", $linkrefid);
00859                         $qtiRespcondition->append_child($qtiConditionvar);
00860                         $qtiRespcondition->append_child($qtiSetvar);
00861                         $qtiRespcondition->append_child($qtiDisplayfeedback);
00862                         $qtiResprocessing->append_child($qtiRespcondition);
00863                 }
00864                 $qtiIdent->append_child($qtiResprocessing);
00865 
00866                 // PART III: qti itemfeedback
00867                 foreach ($this->answers as $index => $answer)
00868                 {
00869                         $qtiItemfeedback = $this->domxml->create_element("itemfeedback");
00870                         $linkrefid = "";
00871                         if ($answer->isStateSet())
00872                         {
00873                                 $linkrefid = "True";
00874                         }
00875                           else
00876                         {
00877                                 $linkrefid = "False_$index";
00878                         }
00879                         $qtiItemfeedback->set_attribute("ident", $linkrefid);
00880                         $qtiItemfeedback->set_attribute("view", "All");
00881                         // qti flow_mat
00882                         $qtiFlowmat = $this->domxml->create_element("flow_mat");
00883                         $qtiMaterial = $this->domxml->create_element("material");
00884                         $qtiMattext = $this->domxml->create_element("mattext");
00885                         // Insert response text for right/wrong answers here!!!
00886                         $qtiMattextText = $this->domxml->create_text_node("");
00887                         $qtiMattext->append_child($qtiMattextText);
00888                         $qtiMaterial->append_child($qtiMattext);
00889                         $qtiFlowmat->append_child($qtiMaterial);
00890                         $qtiItemfeedback->append_child($qtiFlowmat);
00891                         $qtiIdent->append_child($qtiItemfeedback);
00892                 }
00893 
00894                 $xml = $this->domxml->dump_mem(true);
00895                 if (!$a_include_header)
00896                 {
00897                         $pos = strpos($xml, "?>");
00898                         $xml = substr($xml, $pos + 2);
00899                 }
00900 //echo htmlentities($xml);
00901                 return $xml;
00902 
00903         }
00904 
00914   function get_question() {
00915     return $this->question;
00916   }
00917 
00927   function set_question($question = "") {
00928     $this->question = $question;
00929   }
00930 
00940   function get_imagemap_filename() {
00941     return $this->imagemap_filename;
00942   }
00943 
00953   function set_imagemap_filename($imagemap_filename, $imagemap_tempfilename = "") {
00954     if (!empty($imagemap_filename)) {
00955       $this->imagemap_filename = $imagemap_filename;
00956     }
00957     if (!empty($imagemap_tempfilename)) {
00958             $fp = fopen($imagemap_tempfilename, "r");
00959             $contents = fread($fp, filesize($imagemap_tempfilename));
00960       fclose($fp);
00961                         if (preg_match_all("/<area(.+)>/siU", $contents, $matches)) {
00962                         for ($i=0; $i< count($matches[1]); $i++) {
00963                         preg_match("/alt\s*=\s*\"(.+)\"\s*/siU", $matches[1][$i], $alt);
00964                         preg_match("/coords\s*=\s*\"(.+)\"\s*/siU", $matches[1][$i], $coords);
00965                         preg_match("/shape\s*=\s*\"(.+)\"\s*/siU", $matches[1][$i], $shape);
00966                                         $this->add_answer($alt[1], 0.0, FALSE, count($this->answers), $coords[1], $shape[1]);
00967                         }
00968                         }
00969     }
00970         }
00971 
00981   function get_image_filename() {
00982     return $this->image_filename;
00983   }
00984 
00994   function set_image_filename($image_filename, $image_tempfilename = "") {
00995 
00996     if (!empty($image_filename)) 
00997                 {
00998                         $image_filename = str_replace(" ", "_", $image_filename);
00999       $this->image_filename = $image_filename;
01000     }
01001                 if (!empty($image_tempfilename)) {
01002                         $imagepath = $this->getImagePath();
01003                         if (!file_exists($imagepath)) {
01004                                 ilUtil::makeDirParents($imagepath);
01005                         }
01006                         
01007                         if (!ilUtil::moveUploadedFile($image_tempfilename, $image_filename, $imagepath.$image_filename))
01008                         {
01009                                 $this->ilias->raiseError("The image could not be uploaded!", $this->ilias->error_obj->MESSAGE);
01010                         }
01011                 }
01012   }
01013 
01023   function get_imagemap_contents($href = "#") {
01024                 $imagemap_contents = "<map name=\"".$this->title."\"> ";
01025                 for ($i = 0; $i < count($this->answers); $i++) {
01026                         $imagemap_contents .= "<area alt=\"".$this->answers[$i]->get_answertext()."\" ";
01027                         $imagemap_contents .= "shape=\"".$this->answers[$i]->get_area()."\" ";
01028                         $imagemap_contents .= "coords=\"".$this->answers[$i]->get_coords()."\" ";
01029                         $imagemap_contents .= "href=\"$href&selimage=" . $this->answers[$i]->get_order() . "\" /> ";
01030                 }
01031                 $imagemap_contents .= "</map>";
01032     return $imagemap_contents;
01033   }
01034 
01049   function add_answer(
01050     $answertext = "",
01051     $points = 0.0,
01052     $status = 0,
01053     $order = 0,
01054     $coords="",
01055     $area=""
01056   )
01057   {
01058     if (array_key_exists($order, $this->answers)) {
01059       // Antwort einf�gen
01060       $answer = new ASS_AnswerImagemap($answertext, $points, $order, $status, $coords, $area);
01061                         for ($i = count($this->answers) - 1; $i >= $order; $i--) {
01062                                 $this->answers[$i+1] = $this->answers[$i];
01063                                 $this->answers[$i+1]->set_order($i+1);
01064                         }
01065                         $this->answers[$order] = $answer;
01066     } else {
01067       // Anwort anh�ngen
01068       $answer = new ASS_AnswerImagemap($answertext, $points, count($this->answers), $status, $coords, $area);
01069       array_push($this->answers, $answer);
01070     }
01071   }
01072 
01082   function get_answer_count() {
01083     return count($this->answers);
01084   }
01085 
01097   function get_answer($index = 0) {
01098     if ($index < 0) return NULL;
01099     if (count($this->answers) < 1) return NULL;
01100     if ($index >= count($this->answers)) return NULL;
01101     return $this->answers[$index];
01102   }
01103 
01114   function deleteArea($index = 0) {
01115     if ($index < 0) return;
01116     if (count($this->answers) < 1) return;
01117     if ($index >= count($this->answers)) return;
01118     unset($this->answers[$index]);
01119     $this->answers = array_values($this->answers);
01120     for ($i = 0; $i < count($this->answers); $i++) {
01121       if ($this->answers[$i]->get_order() > $index) {
01122         $this->answers[$i]->set_order($i);
01123       }
01124     }
01125   }
01126 
01135   function flush_answers() {
01136     $this->answers = array();
01137   }
01138 
01147   function getMaximumPoints() {
01148                 $points = array("set" => 0, "unset" => 0);
01149                 foreach ($this->answers as $key => $value) {
01150                         if ($value->get_points() > $points["set"])
01151                         {
01152                                 $points["set"] = $value->get_points();
01153                         }
01154                 }
01155                 return $points["set"];
01156   }
01157 
01169         function calculateReachedPoints($user_id, $test_id)
01170         {
01171                 global $ilDB;
01172                 
01173     $found_values = array();
01174     $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01175       $ilDB->quote($user_id),
01176       $ilDB->quote($test_id),
01177       $ilDB->quote($this->getId())
01178     );
01179     $result = $ilDB->query($query);
01180                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01181                 {
01182                         if (strcmp($data->value1, "") != 0)
01183                         {
01184                                 array_push($found_values, $data->value1);
01185                         }
01186                 }
01187                 $points = 0;
01188                 if (count($found_values) > 0)
01189                 {
01190                         foreach ($this->answers as $key => $answer)
01191                         {
01192                                 if ($answer->isStateChecked())
01193                                 {
01194                                         if (in_array($key, $found_values))
01195                                         {
01196                                                 $points += $answer->get_points();
01197                                         }
01198                                 }
01199                         }
01200                 }
01201 
01202                 // check for special scoring options in test
01203                 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
01204                         $ilDB->quote($test_id)
01205                 );
01206                 $result = $ilDB->query($query);
01207                 if ($result->numRows() == 1)
01208                 {
01209                         $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
01210                         if ($row["count_system"] == 1)
01211                         {
01212                                 if ($points != $this->getMaximumPoints())
01213                                 {
01214                                         $points = 0;
01215                                 }
01216                         }
01217                 }
01218                 else
01219                 {
01220                         $points = 0;
01221                 }
01222                 return $points;
01223         }
01224 
01234   function getReachedInformation($user_id, $test_id) {
01235     $found_values = array();
01236     $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01237       $this->ilias->db->quote($user_id),
01238       $this->ilias->db->quote($test_id),
01239       $this->ilias->db->quote($this->getId())
01240     );
01241     $result = $this->ilias->db->query($query);
01242                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01243                 {
01244                         array_push($found_values, $data->value1);
01245                 }
01246                 $counter = 1;
01247                 $user_result = array();
01248                 foreach ($found_values as $key => $value)
01249                 {
01250                         $solution = array(
01251                                 "order" => "$counter",
01252                                 "points" => 0,
01253                                 "true" => 0,
01254                                 "value" => "",
01255                                 );
01256                         if (strlen($value) > 0)
01257                         {
01258                                 $solution["value"] = $value;
01259                                 $solution["points"] = $this->answers[$value]->get_points();
01260                                 if ($this->answers[$value]->isStateChecked())
01261                                 {
01262                                         $solution["true"] = 1;
01263                                 }
01264                         }
01265                         $counter++;
01266                         array_push($user_result, $solution);
01267                 }
01268                 return $user_result;
01269   }
01270 
01281   function saveWorkingData($test_id, $limit_to = LIMIT_NO_LIMIT) {
01282     global $ilDB;
01283                 global $ilUser;
01284     $db =& $ilDB->db;
01285 
01286     $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01287       $db->quote($ilUser->id),
01288       $db->quote($test_id),
01289       $db->quote($this->getId())
01290     );
01291     $result = $db->query($query);
01292 
01293                 $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, NULL, NULL)",
01294                         $db->quote($ilUser->id),
01295                         $db->quote($test_id),
01296                         $db->quote($this->getId()),
01297                         $db->quote($_GET["selImage"])
01298                 );
01299                 $result = $db->query($query);
01300     parent::saveWorkingData($test_id);
01301                 return true;
01302   }
01303 
01304         function syncWithOriginal()
01305         {
01306                 global $ilias;
01307                 if ($this->original_id)
01308                 {
01309                         $complete = 0;
01310                         if ($this->isComplete())
01311                         {
01312                                 $complete = 1;
01313                         }
01314                         $db = & $ilias->db;
01315         
01316                         $estw_time = $this->getEstimatedWorkingTime();
01317                         $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01318         
01319                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, points = %s, image_file = %s, complete = %s WHERE question_id = %s",
01320                                 $db->quote($this->obj_id. ""),
01321                                 $db->quote($this->title . ""),
01322                                 $db->quote($this->comment . ""),
01323                                 $db->quote($this->author . ""),
01324                                 $db->quote($this->question . ""),
01325                                 $db->quote($estw_time . ""),
01326                                 $db->quote($this->getMaximumPoints() . ""),
01327                                 $db->quote($this->image_filename . ""),
01328                                 $db->quote($complete . ""),
01329                                 $db->quote($this->original_id . "")
01330                         );
01331                         $result = $db->query($query);
01332 
01333                         if ($result == DB_OK)
01334                         {
01335                                 // write answers
01336                                 // delete old answers
01337                                 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
01338                                         $db->quote($this->original_id)
01339                                 );
01340                                 $result = $db->query($query);
01341         
01342                                 foreach ($this->answers as $key => $value)
01343                                 {
01344                                         $answer_obj = $this->answers[$key];
01345                                         $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, correctness, coords, area, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, NULL)",
01346                                                 $db->quote($this->original_id . ""),
01347                                                 $db->quote($answer_obj->get_answertext() . ""),
01348                                                 $db->quote($answer_obj->get_points() . ""),
01349                                                 $db->quote($answer_obj->get_order() . ""),
01350                                                 $db->quote($answer_obj->getState() . ""),
01351                                                 $db->quote($answer_obj->get_coords() . ""),
01352                                                 $db->quote($answer_obj->get_area() . "")
01353                                                 );
01354                                         $answer_result = $db->query($query);
01355                                 }
01356                         }
01357                         parent::syncWithOriginal();
01358                 }
01359         }
01360 
01369         function getQuestionType()
01370         {
01371                 return 6;
01372         }
01373 }
01374 
01375 ?>

Generated on Fri Dec 13 2013 10:18:25 for ILIAS Release_3_5_x_branch .rev 46805 by  doxygen 1.7.1