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

assessment/classes/class.assMatchingQuestion.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.assAnswerMatching.php";
00026 
00027 define ("MT_TERMS_PICTURES", 0);
00028 define ("MT_TERMS_DEFINITIONS", 1);
00029 define ("MATCHING_QUESTION_IDENTIFIER", "MATCHING QUESTION");
00040 class ASS_MatchingQuestion extends ASS_Question
00041 {
00049         var $question;
00050 
00058         var $matchingpairs;
00059 
00068         var $matching_type;
00069 
00079         var $points;
00080 
00094         function ASS_MatchingQuestion (
00095                 $title = "",
00096                 $comment = "",
00097                 $author = "",
00098                 $owner = -1,
00099                 $question = "",
00100                 $points = 0.0,
00101                 $matching_type = MT_TERMS_DEFINITIONS
00102         )
00103         {
00104                 $this->ASS_Question($title, $comment, $author, $owner);
00105                 $this->matchingpairs = array();
00106                 $this->question = $question;
00107                 $this->points = $points;
00108                 $this->matching_type = $matching_type;
00109         }
00110 
00119         function isComplete()
00120         {
00121                 if (($this->title) and ($this->author) and ($this->question) and (count($this->matchingpairs)))
00122                 {
00123                         return true;
00124                 }
00125                 else
00126                 {
00127                         return false;
00128                 }
00129         }
00130 
00140         function from_xml($xml_text)
00141         {
00142                 $result = false;
00143                 if (!empty($this->domxml))
00144                 {
00145                         $this->domxml->free();
00146                 }
00147                 $xml_text = preg_replace("/>\s*?</", "><", $xml_text);
00148                 $this->domxml = domxml_open_mem($xml_text);
00149                 if (!empty($this->domxml))
00150                 {
00151                         $root = $this->domxml->document_element();
00152                         $item = $root->first_child();
00153                         $this->setTitle($item->get_attribute("title"));
00154                         $this->gaps = array();
00155                         $itemnodes = $item->child_nodes();
00156                         $materials = array();
00157                         $images = array();
00158                         $shuffle = "";
00159                         foreach ($itemnodes as $index => $node)
00160                         {
00161                                 switch ($node->node_name())
00162                                 {
00163                                         case "qticomment":
00164                                                 $comment = $node->get_content();
00165                                                 if (strpos($comment, "ILIAS Version=") !== false)
00166                                                 {
00167                                                 }
00168                                                 elseif (strpos($comment, "Questiontype=") !== false)
00169                                                 {
00170                                                 }
00171                                                 elseif (strpos($comment, "Author=") !== false)
00172                                                 {
00173                                                         $comment = str_replace("Author=", "", $comment);
00174                                                         $this->setAuthor($comment);
00175                                                 }
00176                                                 else
00177                                                 {
00178                                                         $this->setComment($comment);
00179                                                 }
00180                                                 break;
00181                                         case "duration":
00182                                                 $iso8601period = $node->get_content();
00183                                                 if (preg_match("/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches))
00184                                                 {
00185                                                         $this->setEstimatedWorkingTime($matches[4], $matches[5], $matches[6]);
00186                                                 }
00187                                                 break;
00188                                         case "presentation":
00189                                                 $flow = $node->first_child();
00190                                                 $flownodes = $flow->child_nodes();
00191                                                 foreach ($flownodes as $idx => $flownode)
00192                                                 {
00193                                                         if (strcmp($flownode->node_name(), "material") == 0)
00194                                                         {
00195                                                                 $mattext = $flownode->first_child();
00196                                                                 $this->set_question($mattext->get_content());
00197                                                         }
00198                                                         elseif (strcmp($flownode->node_name(), "response_grp") == 0)
00199                                                         {
00200                                                                 $ident = $flownode->get_attribute("ident");
00201                                                                 if (strcmp($ident, "MQT") == 0)
00202                                                                 {
00203                                                                         $this->set_matching_type(MT_TERMS_DEFINITIONS);
00204                                                                 }
00205                                                                 elseif (strcmp($ident, "MQP") == 0)
00206                                                                 {
00207                                                                         $this->set_matching_type(MT_TERMS_PICTURES);
00208                                                                 }
00209                                                                 $subnodes = $flownode->child_nodes();
00210                                                                 foreach ($subnodes as $node_type)
00211                                                                 {
00212                                                                         switch ($node_type->node_name())
00213                                                                         {
00214                                                                                 case "material":
00215                                                                                         $matlabel = $node_type->get_attribute("label");
00216                                                                                         if (strcmp($matlabel, "suggested_solution") == 0)
00217                                                                                         {
00218                                                                                                 $mattype = $node_type->first_child();
00219                                                                                                 if (strcmp($mattype->node_name(), "mattext") == 0)
00220                                                                                                 {
00221                                                                                                         $suggested_solution = $mattype->get_content();
00222                                                                                                         if ($suggested_solution)
00223                                                                                                         {
00224                                                                                                                 if ($this->getId() < 1)
00225                                                                                                                 {
00226                                                                                                                         $this->saveToDb();
00227                                                                                                                 }
00228                                                                                                                 $this->setSuggestedSolution($suggested_solution, 0, true);
00229                                                                                                         }
00230                                                                                                 }
00231                                                                                         }
00232                                                                                         break;
00233                                                                                 case "render_choice":
00234                                                                                         $render_choice = $node_type;
00235                                                                                         $shuffle = $render_choice->get_attribute("shuffle");
00236                                                                                         $labels = $render_choice->child_nodes();
00237                                                                                         foreach ($labels as $lidx => $response_label)
00238                                                                                         {
00239                                                                                                 $material = $response_label->first_child();
00240                                                                                                 if ($this->get_matching_type() == MT_TERMS_PICTURES)
00241                                                                                                 {
00242                                                                                                         $mattype = $material->first_child();
00243                                                                                                         if (strcmp($mattype->node_name(), "matimage") == 0)
00244                                                                                                         {
00245                                                                                                                 $filename = $mattype->get_attribute("label");
00246                                                                                                                 $image = base64_decode($mattype->get_content());
00247                                                                                                                 $images["$filename"] = $image;
00248                                                                                                                 $materials[$response_label->get_attribute("ident")] = $filename;
00249                                                                                                         }
00250                                                                                                         else
00251                                                                                                         {
00252                                                                                                                 $materials[$response_label->get_attribute("ident")] = $mattype->get_content();
00253                                                                                                         }
00254                                                                                                 }
00255                                                                                                 else
00256                                                                                                 {
00257                                                                                                         $mattext = $material->first_child();
00258                                                                                                         $materials[$response_label->get_attribute("ident")] = $mattext->get_content();
00259                                                                                                 }
00260                                                                                         }
00261                                                                                         break;
00262                                                                         }
00263                                                                 }
00264                                                         }
00265                                                 }
00266                                                 break;
00267                                         case "resprocessing":
00268                                                 $resproc_nodes = $node->child_nodes();
00269                                                 foreach ($resproc_nodes as $index => $respcondition)
00270                                                 {
00271                                                         if (strcmp($respcondition->node_name(), "respcondition") == 0)
00272                                                         {
00273                                                                 $respcondition_array =& ilQTIUtils::_getRespcondition($respcondition);
00274                                                                 $pair = split(",", $respcondition_array["conditionvar"]["value"]);
00275                                                                 $this->add_matchingpair($materials[$pair[0]], $materials[$pair[1]], $respcondition_array["setvar"]["points"], $pair[0], $pair[1]);
00276                                                         }
00277                                                 }
00278                                                 break;
00279                                 }
00280                         }
00281                         if (count($images))
00282                         {
00283                                 $this->saveToDb();
00284                                 foreach ($images as $filename => $image)
00285                                 {
00286                                         if ($filename)
00287                                         {
00288                                                 $imagepath = $this->getImagePath();
00289                                                 if (!file_exists($imagepath))
00290                                                 {
00291                                                         ilUtil::makeDirParents($imagepath);
00292                                                 }
00293                                                 $imagepath .=  $filename;
00294                                                 $fh = fopen($imagepath, "wb");
00295                                                 if ($fh == false)
00296                                                 {
00297                                                         global $ilErr;
00298                                                         $ilErr->raiseError($this->lng->txt("error_save_image_file") . ": $php_errormsg", $ilErr->WARNING);
00299                                                         return;
00300                                                 }
00301                                                 $imagefile = fwrite($fh, $image);
00302                                                 fclose($fh);
00303                                                 // create thumbnail file
00304                                                 $thumbpath = $imagepath . "." . "thumb.jpg";
00305                                                 ilUtil::convertImage($imagepath, $thumbpath, "JPEG", 100);
00306                                         }
00307                                 }
00308                         }
00309                         $result = true;
00310                 }
00311                 return $result;
00312         }
00313 
00323         function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false)
00324         {
00325                 if (!empty($this->domxml))
00326                 {
00327                         $this->domxml->free();
00328                 }
00329                 $xml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<questestinterop></questestinterop>\n";
00330                 $this->domxml = domxml_open_mem($xml_header);
00331                 $root = $this->domxml->document_element();
00332 
00333                 // qti comment with version information
00334                 $qtiComment = $this->domxml->create_element("qticomment");
00335 
00336                 // qti ident
00337                 $qtiIdent = $this->domxml->create_element("item");
00338                 $qtiIdent->set_attribute("ident", "il_".IL_INST_ID."_qst_".$this->getId());
00339                 $qtiIdent->set_attribute("title", $this->getTitle());
00340                 $root->append_child($qtiIdent);
00341 
00342                 // add qti comment
00343                 $qtiComment = $this->domxml->create_element("qticomment");
00344                 $qtiCommentText = $this->domxml->create_text_node($this->getComment());
00345                 $qtiComment->append_child($qtiCommentText);
00346                 $qtiIdent->append_child($qtiComment);
00347                 $qtiComment = $this->domxml->create_element("qticomment");
00348                 $qtiCommentText = $this->domxml->create_text_node("ILIAS Version=".$this->ilias->getSetting("ilias_version"));
00349                 $qtiComment->append_child($qtiCommentText);
00350                 $qtiIdent->append_child($qtiComment);
00351                 $qtiComment = $this->domxml->create_element("qticomment");
00352                 $qtiCommentText = $this->domxml->create_text_node("Questiontype=".MATCHING_QUESTION_IDENTIFIER);
00353                 $qtiComment->append_child($qtiCommentText);
00354                 $qtiIdent->append_child($qtiComment);
00355                 $qtiComment = $this->domxml->create_element("qticomment");
00356                 $qtiCommentText = $this->domxml->create_text_node("Author=".$this->getAuthor());
00357                 $qtiComment->append_child($qtiCommentText);
00358                 $qtiIdent->append_child($qtiComment);
00359                 // add estimated working time
00360                 $qtiDuration = $this->domxml->create_element("duration");
00361                 $workingtime = $this->getEstimatedWorkingTime();
00362                 $qtiDurationText = $this->domxml->create_text_node(sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]));
00363                 $qtiDuration->append_child($qtiDurationText);
00364                 $qtiIdent->append_child($qtiDuration);
00365 
00366                 // PART I: qti presentation
00367                 $qtiPresentation = $this->domxml->create_element("presentation");
00368                 $qtiPresentation->set_attribute("label", $this->getTitle());
00369 
00370                 // add flow to presentation
00371                 $qtiFlow = $this->domxml->create_element("flow");
00372 
00373                 // add material with question text to presentation
00374                 $qtiMaterial = $this->domxml->create_element("material");
00375                 $qtiMatText = $this->domxml->create_element("mattext");
00376                 $qtiMatTextText = $this->domxml->create_text_node($this->get_question());
00377                 $qtiMatText->append_child($qtiMatTextText);
00378                 $qtiMaterial->append_child($qtiMatText);
00379                 $qtiFlow->append_child($qtiMaterial);
00380 
00381                 // add answers to presentation
00382                 $qtiResponseGrp = $this->domxml->create_element("response_grp");
00383                 if ($this->get_matching_type() == MT_TERMS_PICTURES)
00384                 {
00385                         $qtiResponseGrp->set_attribute("ident", "MQP");
00386                         $qtiResponseGrp->set_attribute("rcardinality", "Multiple");
00387                         if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
00388                         {
00389                                 $qtiResponseGrp->set_attribute("output", "javascript");
00390                         }
00391                 }
00392                 else
00393                 {
00394                         $qtiResponseGrp->set_attribute("ident", "MQT");
00395                         $qtiResponseGrp->set_attribute("rcardinality", "Multiple");
00396                         if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
00397                         {
00398                                 $qtiResponseGrp->set_attribute("output", "javascript");
00399                         }
00400                 }
00401                 $solution = $this->getSuggestedSolution(0);
00402                 if (count($solution))
00403                 {
00404                         if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00405                         {
00406                                 $qtiMaterial = $this->domxml->create_element("material");
00407                                 $qtiMaterial->set_attribute("label", "suggested_solution");
00408                                 $qtiMatText = $this->domxml->create_element("mattext");
00409                                 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00410                                 if (strcmp($matches[1], "") != 0)
00411                                 {
00412                                         $intlink = $solution["internal_link"];
00413                                 }
00414                                 $qtiMatTextText = $this->domxml->create_text_node($intlink);
00415                                 $qtiMatText->append_child($qtiMatTextText);
00416                                 $qtiMaterial->append_child($qtiMatText);
00417                                 $qtiResponseGrp->append_child($qtiMaterial);
00418                         }
00419                 }
00420                 $qtiRenderChoice = $this->domxml->create_element("render_choice");
00421 
00422                 // shuffle output
00423                 if ($this->getShuffle())
00424                 {
00425                         $qtiRenderChoice->set_attribute("shuffle", "yes");
00426                 }
00427                 else
00428                 {
00429                         $qtiRenderChoice->set_attribute("shuffle", "no");
00430                 }
00431 
00432                 // add answertext
00433                 $matchingtext_orders = array();
00434                 foreach ($this->matchingpairs as $index => $matchingpair)
00435                 {
00436                         array_push($matchingtext_orders, $matchingpair->getTermId());
00437                 }
00438 
00439                 // shuffle it
00440                 $pkeys = array_keys($this->matchingpairs);
00441                 if ($this->getshuffle() && $a_shuffle)
00442                 {
00443                         $pkeys = $this->pcArrayShuffle($pkeys);
00444                 }
00445 
00446                 // add answers
00447                 foreach ($pkeys as $index)
00448                 {
00449                         $matchingpair = $this->matchingpairs[$index];
00450 
00451                         $qtiResponseLabel = $this->domxml->create_element("response_label");
00452                         $qtiResponseLabel->set_attribute("ident", $matchingpair->getDefinitionId());
00453                         $qtiResponseLabel->set_attribute("match_max", "1");
00454                         $qtiResponseLabel->set_attribute("match_group", join($matchingtext_orders, ","));
00455                         $qtiMaterial = $this->domxml->create_element("material");
00456                         if ($this->get_matching_type() == MT_TERMS_PICTURES)
00457                         {
00458                                 $qtiMatImage = $this->domxml->create_element("matimage");
00459                                 $qtiMatImage->set_attribute("imagtype", "image/jpeg");
00460                                 $qtiMatImage->set_attribute("label", $matchingpair->getPicture());
00461                                 $qtiMatImage->set_attribute("embedded", "base64");
00462                                 $imagepath = $this->getImagePath() . $matchingpair->getPicture();
00463                                 $fh = @fopen($imagepath, "rb");
00464                                 if ($fh == false)
00465                                 {
00466                                         //global $ilErr;
00467                                         //$ilErr->raiseError($this->lng->txt("error_open_image_file"), $ilErr->WARNING);
00468                                         //return;
00469                                 }
00470                                 else
00471                                 {
00472                                         $imagefile = fread($fh, filesize($imagepath));
00473                                         fclose($fh);
00474                                         $base64 = base64_encode($imagefile);
00475                                         $qtiBase64Data = $this->domxml->create_text_node($base64);
00476                                         $qtiMatImage->append_child($qtiBase64Data);
00477                                         $qtiMaterial->append_child($qtiMatImage);
00478                                 }
00479                         }
00480                         else
00481                         {
00482                                 $qtiMatText = $this->domxml->create_element("mattext");
00483                                 $qtiMatTextText = $this->domxml->create_text_node($matchingpair->getDefinition());
00484                                 $qtiMatText->append_child($qtiMatTextText);
00485                                 $qtiMaterial->append_child($qtiMatText);
00486                         }
00487                         $qtiResponseLabel->append_child($qtiMaterial);
00488                         $qtiRenderChoice->append_child($qtiResponseLabel);
00489                 }
00490 
00491                 if ($a_shuffle)
00492                 {
00493                         $pkeys = $this->pcArrayShuffle($pkeys);
00494                 }
00495 
00496                 // add matchingtext
00497                 foreach ($this->matchingpairs as $index => $matchingpair)
00498                 {
00499                         $qtiResponseLabel = $this->domxml->create_element("response_label");
00500                         $qtiResponseLabel->set_attribute("ident", $matchingpair->getTermId());
00501                         $qtiMaterial = $this->domxml->create_element("material");
00502                         $qtiMatText = $this->domxml->create_element("mattext");
00503                         $qtiMatTextText = $this->domxml->create_text_node($matchingpair->getTerm());
00504                         $qtiMatText->append_child($qtiMatTextText);
00505                         $qtiMaterial->append_child($qtiMatText);
00506                         $qtiResponseLabel->append_child($qtiMaterial);
00507                         $qtiRenderChoice->append_child($qtiResponseLabel);
00508                 }
00509                 $qtiResponseGrp->append_child($qtiRenderChoice);
00510                 $qtiFlow->append_child($qtiResponseGrp);
00511                 $qtiPresentation->append_child($qtiFlow);
00512                 $qtiIdent->append_child($qtiPresentation);
00513 
00514                 // PART II: qti resprocessing
00515                 $qtiResprocessing = $this->domxml->create_element("resprocessing");
00516                 $qtiOutcomes = $this->domxml->create_element("outcomes");
00517                 $qtiDecvar = $this->domxml->create_element("decvar");
00518                 $qtiOutcomes->append_child($qtiDecvar);
00519                 $qtiResprocessing->append_child($qtiOutcomes);
00520 
00521                 // add response conditions
00522                 foreach ($this->matchingpairs as $index => $matchingpair)
00523                 {
00524                         $qtiRespcondition = $this->domxml->create_element("respcondition");
00525                         $qtiRespcondition->set_attribute("continue", "Yes");
00526                         // qti conditionvar
00527                         $qtiConditionvar = $this->domxml->create_element("conditionvar");
00528                         $qtiVarsubset = $this->domxml->create_element("varsubset");
00529                         if ($this->get_matching_type() == MT_TERMS_PICTURES)
00530                         {
00531                                 $qtiVarsubset->set_attribute("respident", "MQP");
00532                         }
00533                         else
00534                         {
00535                                 $qtiVarsubset->set_attribute("respident", "MQT");
00536                         }
00537                         $qtiVarsubsetText = $this->domxml->create_text_node($matchingpair->getTermId() . "," . $matchingpair->getDefinitionId());
00538                         $qtiVarsubset->append_child($qtiVarsubsetText);
00539                         $qtiConditionvar->append_child($qtiVarsubset);
00540                         // qti setvar
00541                         $qtiSetvar = $this->domxml->create_element("setvar");
00542                         $qtiSetvar->set_attribute("action", "Add");
00543                         $qtiSetvarText = $this->domxml->create_text_node($matchingpair->getPoints());
00544                         $qtiSetvar->append_child($qtiSetvarText);
00545                         // qti displayfeedback
00546                         $qtiDisplayfeedback = $this->domxml->create_element("displayfeedback");
00547                         $qtiDisplayfeedback->set_attribute("feedbacktype", "Response");
00548                         $qtiDisplayfeedback->set_attribute("linkrefid", "correct_" . $matchingpair->getTermId() . "_" . $matchingpair->getDefinitionId());
00549                         $qtiRespcondition->append_child($qtiConditionvar);
00550                         $qtiRespcondition->append_child($qtiSetvar);
00551                         $qtiRespcondition->append_child($qtiDisplayfeedback);
00552                         $qtiResprocessing->append_child($qtiRespcondition);
00553                 }
00554                 $qtiIdent->append_child($qtiResprocessing);
00555 
00556                 // PART III: qti itemfeedback
00557                 foreach ($this->matchingpairs as $index => $matchingpair)
00558                 {
00559                         $qtiItemfeedback = $this->domxml->create_element("itemfeedback");
00560                         $qtiItemfeedback->set_attribute("ident", "correct_" . $matchingpair->getTermId() . "_" . $matchingpair->getDefinitionId());
00561                         $qtiItemfeedback->set_attribute("view", "All");
00562                         // qti flow_mat
00563                         $qtiFlowmat = $this->domxml->create_element("flow_mat");
00564                         $qtiMaterial = $this->domxml->create_element("material");
00565                         $qtiMattext = $this->domxml->create_element("mattext");
00566                         // Insert response text for right/wrong answers here!!!
00567                         $qtiMattextText = $this->domxml->create_text_node("");
00568                         $qtiMattext->append_child($qtiMattextText);
00569                         $qtiMaterial->append_child($qtiMattext);
00570                         $qtiFlowmat->append_child($qtiMaterial);
00571                         $qtiItemfeedback->append_child($qtiFlowmat);
00572                         $qtiIdent->append_child($qtiItemfeedback);
00573                 }
00574 
00575                 $xml = $this->domxml->dump_mem(true);
00576                 if (!$a_include_header)
00577                 {
00578                         $pos = strpos($xml, "?>");
00579                         $xml = substr($xml, $pos + 2);
00580                 }
00581 //echo htmlentities($xml);
00582                 return $xml;
00583 
00584         }
00585 
00594         function saveToDb($original_id = "")
00595         {
00596                 global $ilias;
00597 
00598                 $db =& $ilias->db;
00599                 $complete = 0;
00600                 if ($this->isComplete())
00601                 {
00602                         $complete = 1;
00603                 }
00604                 $estw_time = $this->getEstimatedWorkingTime();
00605                 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00606 
00607                 if ($original_id)
00608                 {
00609                         $original_id = $db->quote($original_id);
00610                 }
00611                 else
00612                 {
00613                         $original_id = "NULL";
00614                 }
00615 
00616                 if ($this->id == -1)
00617                 {
00618                         // Neuen Datensatz schreiben
00619                         $now = getdate();
00620                         $question_type = $this->getQuestionType();
00621                         $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00622                         $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, working_time, matching_type, points, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00623                                 $db->quote($question_type. ""),
00624                                 $db->quote($this->obj_id. ""),
00625                                 $db->quote($this->title. ""),
00626                                 $db->quote($this->comment. ""),
00627                                 $db->quote($this->author. ""),
00628                                 $db->quote($this->owner. ""),
00629                                 $db->quote($this->question. ""),
00630                                 $db->quote($estw_time. ""),
00631                                 $db->quote($this->matching_type. ""),
00632                                 $db->quote($this->points. ""),
00633                                 $db->quote($complete. ""),
00634                                 $db->quote($created. ""),
00635                                 $original_id
00636                         );
00637 
00638                         $result = $db->query($query);
00639                         if ($result == DB_OK)
00640                         {
00641                                 $this->id = $this->ilias->db->getLastInsertId();
00642 
00643                                 // create page object of question
00644                                 $this->createPageObject();
00645 
00646                                 // Falls die Frage in einen Test eingef�gt werden soll, auch diese Verbindung erstellen
00647                                 if ($this->getTestId() > 0)
00648                                 {
00649                                         $this->insertIntoTest($this->getTestId());
00650                                 }
00651                         }
00652                 }
00653                 else
00654                 {
00655                         // Vorhandenen Datensatz aktualisieren
00656                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time=%s, matching_type = %s, points = %s, complete = %s WHERE question_id = %s",
00657                                 $db->quote($this->obj_id. ""),
00658                                 $db->quote($this->title. ""),
00659                                 $db->quote($this->comment. ""),
00660                                 $db->quote($this->author. ""),
00661                                 $db->quote($this->question. ""),
00662                                 $db->quote($estw_time. ""),
00663                                 $db->quote($this->matching_type. ""),
00664                                 $db->quote($this->points. ""),
00665                                 $db->quote($complete. ""),
00666                                 $db->quote($this->id. "")
00667                         );
00668                         $result = $db->query($query);
00669                 }
00670 
00671                 if ($result == DB_OK)
00672                 {
00673                         // Antworten schreiben
00674                         // alte Antworten l�schen
00675                         $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
00676                                 $db->quote($this->id)
00677                         );
00678                         $result = $db->query($query);
00679 
00680                         // Anworten wegschreiben
00681                         foreach ($this->matchingpairs as $key => $value)
00682                         {
00683                                 $matching_obj = $this->matchingpairs[$key];
00684                                 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, matchingtext, matching_order, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
00685                                         $db->quote($this->id),
00686                                         $db->quote($matching_obj->getTerm() . ""),
00687                                         $db->quote($matching_obj->getPoints() . ""),
00688                                         $db->quote($matching_obj->getTermId() . ""),
00689                                         $db->quote($matching_obj->getDefinition() . ""),
00690                                         $db->quote($matching_obj->getDefinitionId() . "")
00691                                 );
00692                                 $matching_result = $db->query($query);
00693                         }
00694                 }
00695                 parent::saveToDb($original_id);
00696         }
00697 
00707         function loadFromDb($question_id)
00708         {
00709                 global $ilias;
00710                 $db =& $ilias->db;
00711 
00712                 $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
00713                         $db->quote($question_id)
00714                 );
00715                 $result = $db->query($query);
00716                 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00717                 {
00718                         if ($result->numRows() == 1)
00719                         {
00720                                 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00721                                 $this->id = $question_id;
00722                                 $this->title = $data->title;
00723                                 $this->comment = $data->comment;
00724                                 $this->author = $data->author;
00725                                 $this->solution_hint = $data->solution_hint;
00726                                 $this->obj_id = $data->obj_fi;
00727                                 $this->original_id = $data->original_id;
00728                                 $this->owner = $data->owner;
00729                                 $this->matching_type = $data->matching_type;
00730                                 $this->question = $data->question_text;
00731                                 $this->points = $data->points;
00732                                 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00733                         }
00734 
00735                         $query = sprintf("SELECT * FROM qpl_answers WHERE question_fi = %s ORDER BY answer_id ASC",
00736                                 $db->quote($question_id)
00737                         );
00738                         $result = $db->query($query);
00739                         if (strcmp(strtolower(get_class($result)), db_result) == 0)
00740                         {
00741                                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00742                                 {
00743                                         array_push($this->matchingpairs, new ASS_AnswerMatching($data->answertext, $data->points, $data->aorder, $data->matchingtext, $data->matching_order));
00744                                 }
00745                         }
00746                 }
00747                 parent::loadFromDb($question_id);
00748         }
00749 
00757         function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00758         {
00759                 if ($this->id <= 0)
00760                 {
00761                         // The question has not been saved. It cannot be duplicated
00762                         return;
00763                 }
00764                 // duplicate the question in database
00765                 $clone = $this;
00766                 $original_id = $this->id;
00767                 if ($original_id <= 0)
00768                 {
00769                         $original_id = "";
00770                 }
00771                 $clone->id = -1;
00772                 if ($title)
00773                 {
00774                         $clone->setTitle($title);
00775                 }
00776                 if ($author)
00777                 {
00778                         $clone->setAuthor($author);
00779                 }
00780                 if ($owner)
00781                 {
00782                         $clone->setOwner($owner);
00783                 }
00784                 if ($for_test)
00785                 {
00786                         $clone->saveToDb($original_id);
00787                 }
00788                 else
00789                 {
00790                         $clone->saveToDb();
00791                 }
00792 
00793                 // copy question page content
00794                 $clone->copyPageOfQuestion($original_id);
00795 
00796                 // duplicate the image
00797                 $clone->duplicateImages($original_id);
00798                 return $clone->id;
00799         }
00800 
00801         function duplicateImages($question_id)
00802         {
00803                 if ($this->get_matching_type() == MT_TERMS_PICTURES)
00804                 {
00805                         $imagepath = $this->getImagePath();
00806                         $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00807                         if (!file_exists($imagepath))
00808                         {
00809                                 ilUtil::makeDirParents($imagepath);
00810                         }
00811                         foreach ($this->matchingpairs as $answer)
00812                         {
00813                                 $filename = $answer->getPicture();
00814                                 if (!copy($imagepath_original . $filename, $imagepath . $filename))
00815                                 {
00816                                         print "image could not be duplicated!!!! ";
00817                                 }
00818                                 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg"))
00819                                 {
00820                                         print "image thumbnail could not be duplicated!!!! ";
00821                                 }
00822                         }
00823                 }
00824         }
00825 
00835         function set_question($question = "")
00836         {
00837                 $this->question = $question;
00838         }
00839 
00849         function set_matching_type($matching_type = MT_TERMS_DEFINITIONS)
00850         {
00851                 $this->matching_type = $matching_type;
00852         }
00853 
00863         function get_question()
00864         {
00865                 return $this->question;
00866         }
00867 
00877         function get_matching_type()
00878         {
00879                 return $this->matching_type;
00880         }
00881 
00896         function add_matchingpair(
00897                 $term = "",
00898                 $picture_or_definition = "",
00899                 $points = 0.0,
00900                 $term_id = 0,
00901                 $picture_or_definition_id = 0
00902         )
00903         {
00904                 // append answer
00905                 if ($term_id == 0)
00906                 {
00907                         $term_id = $this->get_random_id();
00908                 }
00909 
00910                 if ($picture_or_definition_id == 0)
00911                 {
00912                         $picture_or_definition_id = $this->get_random_id();
00913                 }
00914                 $matchingpair = new ASS_AnswerMatching($term, $points, $term_id, $picture_or_definition, $picture_or_definition_id);
00915                 array_push($this->matchingpairs, $matchingpair);
00916         }
00917 
00929         function get_matchingpair($index = 0)
00930         {
00931                 if ($index < 0)
00932                 {
00933                         return NULL;
00934                 }
00935                 if (count($this->matchingpairs) < 1)
00936                 {
00937                         return NULL;
00938                 }
00939                 if ($index >= count($this->matchingpairs))
00940                 {
00941                         return NULL;
00942                 }
00943                 return $this->matchingpairs[$index];
00944         }
00945 
00956         function delete_matchingpair($index = 0)
00957         {
00958                 if ($index < 0)
00959                 {
00960                         return;
00961                 }
00962                 if (count($this->matchingpairs) < 1)
00963                 {
00964                         return;
00965                 }
00966                 if ($index >= count($this->matchingpairs))
00967                 {
00968                         return;
00969                 }
00970                 unset($this->matchingpairs[$index]);
00971                 $this->matchingpairs = array_values($this->matchingpairs);
00972         }
00973 
00982         function flush_matchingpairs()
00983         {
00984                 $this->matchingpairs = array();
00985         }
00986 
00996         function get_matchingpair_count()
00997         {
00998                 return count($this->matchingpairs);
00999         }
01000 
01010         function get_points()
01011         {
01012                 return $this->points;
01013         }
01014 
01024         function set_points($points = 0.0)
01025         {
01026                 $this->points = $points;
01027         }
01028 
01038         function getReachedPoints($user_id, $test_id)
01039         {
01040                 $found_value1 = array();
01041                 $found_value2 = array();
01042                 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01043                         $this->ilias->db->quote($user_id),
01044                         $this->ilias->db->quote($test_id),
01045                         $this->ilias->db->quote($this->getId())
01046                 );
01047                 $result = $this->ilias->db->query($query);
01048                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01049                 {
01050                         if (strcmp($data->value1, "") != 0)
01051                         {
01052                                 array_push($found_value1, $data->value1);
01053                                 array_push($found_value2, $data->value2);
01054                         }
01055                 }
01056                 $points = 0;
01057                 foreach ($found_value2 as $key => $value)
01058                 {
01059                         foreach ($this->matchingpairs as $answer_key => $answer_value)
01060                         {
01061                                 if (($answer_value->getDefinitionId() == $value) and ($answer_value->getTermId() == $found_value1[$key]))
01062                                 {
01063                                         $points += $answer_value->getPoints();
01064                                 }
01065                         }
01066                 }
01067                 return $points;
01068         }
01069 
01079         function getReachedInformation($user_id, $test_id)
01080         {
01081                 $found_value1 = array();
01082                 $found_value2 = array();
01083                 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01084                         $this->ilias->db->quote($user_id),
01085                         $this->ilias->db->quote($test_id),
01086                         $this->ilias->db->quote($this->getId())
01087                 );
01088                 $result = $this->ilias->db->query($query);
01089                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01090                 {
01091                         array_push($found_value1, $data->value1);
01092                         array_push($found_value2, $data->value2);
01093                 }
01094                 $counter = 1;
01095                 $user_result = array();
01096                 foreach ($found_value1 as $key => $value)
01097                 {
01098                         $solution = array(
01099                                 "order" => "$counter",
01100                                 "points" => 0,
01101                                 "true" => 0,
01102                                 "term" => "",
01103                                 "definition" => ""
01104                         );
01105                         foreach ($this->matchingpairs as $answer_key => $answer_value)
01106                         {
01107                                 if (($answer_value->getDefinitionId() == $found_value2[$key]) and ($answer_value->getTermId() == $value))
01108                                 {
01109                                         $points += $answer_value->getPoints();
01110                                         $solution["points"] = $answer_value->getPoints();
01111                                         $solution["term"] = $value;
01112                                         $solution["definition"] = $found_value2[$key];
01113                                         $solution["true"] = 1;
01114                                 }
01115                                 else
01116                                 {
01117                                         $solution["term"] = $value;
01118                                         $solution["definition"] = $found_value2[$key];
01119                                 }
01120                         }
01121                         $counter++;
01122                         array_push($user_result, $solution);
01123                 }
01124                 return $user_result;
01125         }
01126 
01135         function getMaximumPoints()
01136         {
01137                 $points = 0;
01138                 foreach ($this->matchingpairs as $key => $value)
01139                 {
01140                         if ($value->getPoints() > 0)
01141                         {
01142                                 $points += $value->getPoints();
01143                         }
01144                 }
01145                 return $points;
01146         }
01147 
01158         function set_image_file($image_filename, $image_tempfilename = "")
01159         {
01160                 $result = 0;
01161                 if (!empty($image_tempfilename))
01162                 {
01163                         $imagepath = $this->getImagePath();
01164                         if (!file_exists($imagepath))
01165                         {
01166                                 ilUtil::makeDirParents($imagepath);
01167                         }
01168                         //if (!move_uploaded_file($image_tempfilename, $imagepath . $image_filename))
01169                         if (!ilUtil::moveUploadedFile($image_tempfilename, $image_filename, $imagepath.$image_filename))
01170                         {
01171                                 $result = 2;
01172                         }
01173                         else
01174                         {
01175                                 require_once "./content/classes/Media/class.ilObjMediaObject.php";
01176                                 $mimetype = ilObjMediaObject::getMimeType($imagepath . $image_filename);
01177                                 if (!preg_match("/^image/", $mimetype))
01178                                 {
01179                                         unlink($imagepath . $image_filename);
01180                                         $result = 1;
01181                                 }
01182                                 else
01183                                 {
01184                                         // create thumbnail file
01185                                         $thumbpath = $imagepath . $image_filename . "." . "thumb.jpg";
01186                                         ilUtil::convertImage($imagepath.$image_filename, $thumbpath, "JPEG", 100);
01187                                 }
01188                         }
01189                 }
01190                 return $result;
01191         }
01192 
01202         function checkSaveData()
01203         {
01204                 $result = true;
01205                 $matching_values = array();
01206                 foreach ($_POST as $key => $value)
01207                 {
01208                         if (preg_match("/^sel_matching_(\d+)/", $key, $matches))
01209                         {
01210                                 if ((strcmp($value, "") != 0) && ($value != -1))
01211                                 {
01212                                         array_push($matching_values, $value);
01213                                 }
01214                         }
01215                 }
01216                 $check_matching = array_flip($matching_values);
01217                 if (count($check_matching) != count($matching_values))
01218                 {
01219                         // duplicate matching values!!!
01220                         $result = false;
01221                         sendInfo($this->lng->txt("duplicate_matching_values_selected"));
01222                 }
01223                 return $result;
01224         }
01225 
01236         function saveWorkingData($test_id, $limit_to = LIMIT_NO_LIMIT)
01237         {
01238                 global $ilDB;
01239                 global $ilUser;
01240                 $saveWorkingDataResult = $this->checkSaveData();
01241                 if ($saveWorkingDataResult)
01242                 {
01243                         $db =& $ilDB->db;
01244         
01245                         $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01246                                 $db->quote($ilUser->id),
01247                                 $db->quote($test_id),
01248                                 $db->quote($this->getId())
01249                         );
01250                         $result = $db->query($query);
01251         
01252                         foreach ($_POST as $key => $value)
01253                         {
01254                                 if (preg_match("/^sel_matching_(\d+)/", $key, $matches))
01255                                 {
01256                                         if (!(preg_match("/initial_value_\d+/", $value)))
01257                                         {
01258                                                 $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)",
01259                                                         $db->quote($ilUser->id),
01260                                                         $db->quote($test_id),
01261                                                         $db->quote($this->getId()),
01262                                                         $db->quote($value),
01263                                                         $db->quote($matches[1])
01264                                                 );
01265                                                 $result = $db->query($query);
01266                                         }
01267                                 }
01268                         }
01269                         $saveWorkingDataResult = true;
01270                 }
01271                 //    parent::saveWorkingData($limit_to);
01272                 return $saveWorkingDataResult;
01273         }
01274 
01275         function get_random_id()
01276         {
01277                 mt_srand((double)microtime()*1000000);
01278                 $random_number = mt_rand(1, 100000);
01279                 $found = FALSE;
01280                 while ($found)
01281                 {
01282                         $found = FALSE;
01283                         foreach ($this->matchingpairs as $key => $value)
01284                         {
01285                                 if (($value->getTermId() == $random_number) || ($value->getDefinitionId() == $random_number))
01286                                 {
01287                                         $found = TRUE;
01288                                         $random_number++;
01289                                 }
01290                         }
01291                 }
01292                 return $random_number;
01293         }
01294 
01295         function syncWithOriginal()
01296         {
01297                 global $ilias;
01298                 if ($this->original_id)
01299                 {
01300                         $complete = 0;
01301                         if ($this->isComplete())
01302                         {
01303                                 $complete = 1;
01304                         }
01305                         $db = & $ilias->db;
01306         
01307                         $estw_time = $this->getEstimatedWorkingTime();
01308                         $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01309         
01310                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time=%s, matching_type = %s, points = %s, complete = %s WHERE question_id = %s",
01311                                 $db->quote($this->obj_id. ""),
01312                                 $db->quote($this->title. ""),
01313                                 $db->quote($this->comment. ""),
01314                                 $db->quote($this->author. ""),
01315                                 $db->quote($this->question. ""),
01316                                 $db->quote($estw_time. ""),
01317                                 $db->quote($this->matching_type. ""),
01318                                 $db->quote($this->points. ""),
01319                                 $db->quote($complete. ""),
01320                                 $db->quote($this->original_id. "")
01321                         );
01322                         $result = $db->query($query);
01323 
01324                         if ($result == DB_OK)
01325                         {
01326                                 // write answers
01327                                 // delete old answers
01328                                 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
01329                                         $db->quote($this->original_id)
01330                                 );
01331                                 $result = $db->query($query);
01332         
01333                                 foreach ($this->matchingpairs as $key => $value)
01334                                 {
01335                                         $matching_obj = $this->matchingpairs[$key];
01336                                         $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, matchingtext, matching_order, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
01337                                                 $db->quote($this->original_id . ""),
01338                                                 $db->quote($matching_obj->getTerm() . ""),
01339                                                 $db->quote($matching_obj->getPoints() . ""),
01340                                                 $db->quote($matching_obj->getTermId() . ""),
01341                                                 $db->quote($matching_obj->getDefinition() . ""),
01342                                                 $db->quote($matching_obj->getDefinitionId() . "")
01343                                         );
01344                                         $matching_result = $db->query($query);
01345                                 }
01346                         }
01347                         parent::syncWithOriginal();
01348                 }
01349         }
01350 
01351         function pc_array_shuffle($array) {
01352                 $i = count($array);
01353                 mt_srand((double)microtime()*1000000);
01354                 while(--$i) 
01355                 {
01356                         $j = mt_rand(0, $i);
01357                         if ($i != $j) 
01358                         {
01359                                 // swap elements
01360                                 $tmp = $array[$j];
01361                                 $array[$j] = $array[$i];
01362                                 $array[$i] = $tmp;
01363                         }
01364                 }
01365                 return $array;
01366         }
01367         
01368         function createRandomSolution($test_id, $user_id)
01369         {
01370                 global $ilDB;
01371                 global $ilUser;
01372                 $db =& $ilDB->db;
01373 
01374                 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01375                         $db->quote($user_id),
01376                         $db->quote($test_id),
01377                         $db->quote($this->getId())
01378                 );
01379                 $result = $db->query($query);
01380 
01381                 $terms = array();
01382                 $definitions = array();
01383                 
01384                 foreach ($this->matchingpairs as $key => $pair)
01385                 {
01386                         array_push($terms, $pair->getTermId());
01387                         array_push($definitions, $pair->getDefinitionId());
01388                 }
01389                 $definitions = $this->pc_array_shuffle($definitions);
01390                 foreach ($terms as $key => $value)
01391                 {
01392                         $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)",
01393                                 $db->quote($user_id),
01394                                 $db->quote($test_id),
01395                                 $db->quote($this->getId()),
01396                                 $db->quote($value),
01397                                 $db->quote($definitions[$key])
01398                         );
01399                         $result = $db->query($query);
01400                 }
01401         }
01402 
01411         function getQuestionType()
01412         {
01413                 return 4;
01414         }
01415         
01416 }
01417 
01418 ?>

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