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

assessment/classes/class.assOrderingQuestion.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.assAnswerOrdering.php";
00026 
00027 define ("OQ_PICTURES", 0);
00028 define ("OQ_TERMS", 1);
00029 
00030 define ("ORDERING_QUESTION_IDENTIFIER", "ORDERING QUESTION");
00031 
00042 class ASS_OrderingQuestion extends ASS_Question
00043 {
00051         var $question;
00052 
00060         var $answers;
00061 
00070         var $ordering_type;
00071 
00084         function ASS_OrderingQuestion (
00085                 $title = "",
00086                 $comment = "",
00087                 $author = "",
00088                 $owner = -1,
00089                 $question = "",
00090                 $ordering_type = OQ_TERMS
00091         )
00092         {
00093                 $this->ASS_Question($title, $comment, $author, $owner);
00094                 $this->answers = array();
00095                 $this->question = $question;
00096                 $this->ordering_type = $ordering_type;
00097         }
00098 
00107         function isComplete()
00108         {
00109                 if (($this->title) and ($this->author) and ($this->question) and (count($this->answers)))
00110                 {
00111                         return true;
00112                 }
00113                         else
00114                 {
00115                         return false;
00116                 }
00117         }
00118 
00128         function from_xml($xml_text)
00129         {
00130                 $result = false;
00131                 if (!empty($this->domxml))
00132                 {
00133                         $this->domxml->free();
00134                 }
00135                 $xml_text = preg_replace("/>\s*?</", "><", $xml_text);
00136                 $this->domxml = domxml_open_mem($xml_text);
00137                 if (!empty($this->domxml))
00138                 {
00139                         $root = $this->domxml->document_element();
00140                         $item = $root->first_child();
00141                         $this->setTitle($item->get_attribute("title"));
00142                         $this->gaps = array();
00143                         $itemnodes = $item->child_nodes();
00144                         $materials = array();
00145                         $images = array();
00146                         $shuffle = "";
00147                         foreach ($itemnodes as $index => $node)
00148                         {
00149                                 switch ($node->node_name())
00150                                 {
00151                                         case "qticomment":
00152                                                 $comment = $node->get_content();
00153                                                 if (strpos($comment, "ILIAS Version=") !== false)
00154                                                 {
00155                                                 }
00156                                                 elseif (strpos($comment, "Questiontype=") !== false)
00157                                                 {
00158                                                 }
00159                                                 elseif (strpos($comment, "Author=") !== false)
00160                                                 {
00161                                                         $comment = str_replace("Author=", "", $comment);
00162                                                         $this->setAuthor($comment);
00163                                                 }
00164                                                 else
00165                                                 {
00166                                                         $this->setComment($comment);
00167                                                 }
00168                                                 break;
00169                                         case "itemmetadata":
00170                                                 $md_array = array();
00171                                                 $metanodes = $node->child_nodes();
00172                                                 foreach ($metanodes as $metanode)
00173                                                 {
00174                                                         switch ($metanode->node_name())
00175                                                         {
00176                                                                 case "qtimetadata":
00177                                                                         $metafields = $metanode->child_nodes();
00178                                                                         foreach ($metafields as $metafield)
00179                                                                         {
00180                                                                                 switch ($metafield->node_name())
00181                                                                                 {
00182                                                                                         case "qtimetadatafield":
00183                                                                                                 $metafieldlist = $metafield->child_nodes();
00184                                                                                                 $md = array("label" => "", "entry" => "");
00185                                                                                                 foreach ($metafieldlist as $attr)
00186                                                                                                 {
00187                                                                                                         switch ($attr->node_name())
00188                                                                                                         {
00189                                                                                                                 case "fieldlabel":
00190                                                                                                                         $md["label"] = $attr->get_content();
00191                                                                                                                         break;
00192                                                                                                                 case "fieldentry":
00193                                                                                                                         $md["entry"] = $attr->get_content();
00194                                                                                                                         break;
00195                                                                                                         }
00196                                                                                                 }
00197                                                                                                 array_push($md_array, $md);
00198                                                                                                 break;
00199                                                                                 }
00200                                                                         }
00201                                                                         break;
00202                                                         }
00203                                                 }
00204                                                 foreach ($md_array as $md)
00205                                                 {
00206                                                         switch ($md["label"])
00207                                                         {
00208                                                                 case "ILIAS_VERSION":
00209                                                                         break;
00210                                                                 case "QUESTIONTYPE":
00211                                                                         break;
00212                                                                 case "AUTHOR":
00213                                                                         $this->setAuthor($md["entry"]);
00214                                                                         break;
00215                                                         }
00216                                                 }
00217                                                 break;
00218                                         case "duration":
00219                                                 $iso8601period = $node->get_content();
00220                                                 if (preg_match("/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches))
00221                                                 {
00222                                                         $this->setEstimatedWorkingTime($matches[4], $matches[5], $matches[6]);
00223                                                 }
00224                                                 break;
00225                                         case "presentation":
00226                                                 $flow = $node->first_child();
00227                                                 $flownodes = $flow->child_nodes();
00228                                                 foreach ($flownodes as $idx => $flownode)
00229                                                 {
00230                                                         if (strcmp($flownode->node_name(), "material") == 0)
00231                                                         {
00232                                                                 $mattext = $flownode->first_child();
00233                                                                 $this->set_question($mattext->get_content());
00234                                                         }
00235                                                         elseif (strcmp($flownode->node_name(), "response_lid") == 0)
00236                                                         {
00237                                                                 $ident = $flownode->get_attribute("ident");
00238                                                                 if (strcmp($ident, "OQT") == 0)
00239                                                                 {
00240                                                                         $this->set_ordering_type(OQ_TERMS);
00241                                                                 }
00242                                                                 elseif (strcmp($ident, "OQP") == 0)
00243                                                                 {
00244                                                                         $this->set_ordering_type(OQ_PICTURES);
00245                                                                 }
00246                                                                 $subnodes = $flownode->child_nodes();
00247                                                                 foreach ($subnodes as $node_type)
00248                                                                 {
00249                                                                         switch ($node_type->node_name())
00250                                                                         {
00251                                                                                 case "material":
00252                                                                                         $matlabel = $node_type->get_attribute("label");
00253                                                                                         if (strcmp($matlabel, "suggested_solution") == 0)
00254                                                                                         {
00255                                                                                                 $mattype = $node_type->first_child();
00256                                                                                                 if (strcmp($mattype->node_name(), "mattext") == 0)
00257                                                                                                 {
00258                                                                                                         $suggested_solution = $mattype->get_content();
00259                                                                                                         if ($suggested_solution)
00260                                                                                                         {
00261                                                                                                                 if ($this->getId() < 1)
00262                                                                                                                 {
00263                                                                                                                         $this->saveToDb();
00264                                                                                                                 }
00265                                                                                                                 $this->setSuggestedSolution($suggested_solution, 0, true);
00266                                                                                                         }
00267                                                                                                 }
00268                                                                                         }
00269                                                                                         break;
00270                                                                                 case "render_choice":
00271                                                                                         $render_choice = $node_type;
00272                                                                                         $shuffle = $render_choice->get_attribute("shuffle");
00273                                                                                         $shuf = 0;
00274                                                                                         if (strcmp(strtolower($shuffle), "yes") == 0)
00275                                                                                         {
00276                                                                                                 $shuf = 1;
00277                                                                                         }
00278                                                                                         $this->setShuffle($shuf);
00279                                                                                         $labels = $render_choice->child_nodes();
00280                                                                                         foreach ($labels as $lidx => $response_label)
00281                                                                                         {
00282                                                                                                 $material = $response_label->first_child();
00283                                                                                                 if ($this->get_ordering_type() == OQ_PICTURES)
00284                                                                                                 {
00285                                                                                                         $matimage = $material->first_child();
00286                                                                                                         $filename = $matimage->get_attribute("label");
00287                                                                                                         $image = base64_decode($matimage->get_content());
00288                                                                                                         $images["$filename"] = $image;
00289                                                                                                         $materials[$response_label->get_attribute("ident")] = $filename;
00290                                                                                                 }
00291                                                                                                 else
00292                                                                                                 {
00293                                                                                                         $mattext = $material->first_child();
00294                                                                                                         $materials[$response_label->get_attribute("ident")] = $mattext->get_content();
00295                                                                                                 }
00296                                                                                         }
00297                                                                         }
00298                                                                 }
00299                                                         }
00300                                                 }
00301                                                 break;
00302                                         case "resprocessing":
00303                                                 $resproc_nodes = $node->child_nodes();
00304                                                 foreach ($resproc_nodes as $index => $respcondition)
00305                                                 {
00306                                                         if (strcmp($respcondition->node_name(), "respcondition") == 0)
00307                                                         {
00308                                                                 $respcondition_array =& ilQTIUtils::_getRespcondition($respcondition);
00309                                                                 $this->add_answer($materials[$respcondition_array["conditionvar"]["value"]], $respcondition_array["setvar"]["points"], count($this->answers), $respcondition_array["conditionvar"]["index"]);
00310                                                         }
00311                                                 }
00312                                                 break;
00313                                 }
00314                         }
00315                         if (count($images))
00316                         {
00317                                 $this->saveToDb();
00318                                 foreach ($images as $filename => $image)
00319                                 {
00320                                         if ($filename)
00321                                         {
00322                                                 $imagepath = $this->getImagePath();
00323                                                 if (!file_exists($imagepath))
00324                                                 {
00325                                                         ilUtil::makeDirParents($imagepath);
00326                                                 }
00327                                                 $imagepath .=  $filename;
00328                                                 $fh = fopen($imagepath, "wb");
00329                                                 if ($fh == false)
00330                                                 {
00331                                                         global $ilErr;
00332                                                         $ilErr->raiseError($this->lng->txt("error_save_image_file") . ": $php_errormsg", $ilErr->MESSAGE);
00333                                                         return;
00334                                                 }
00335                                                 $imagefile = fwrite($fh, $image);
00336                                                 fclose($fh);
00337                                                 // create thumbnail file
00338                                                 $thumbpath = $imagepath . "." . "thumb.jpg";
00339                                                 ilUtil::convertImage($imagepath, $thumbpath, "JPEG", 100);
00340                                         }
00341                                 }
00342                         }
00343                         $result = true;
00344                 }
00345                 return $result;
00346         }
00347 
00357         function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false)
00358         {
00359                 if (!empty($this->domxml))
00360                 {
00361                         $this->domxml->free();
00362                 }
00363                 $xml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<questestinterop></questestinterop>\n";
00364                 $this->domxml = domxml_open_mem($xml_header);
00365                 $root = $this->domxml->document_element();
00366                 // qti ident
00367                 $qtiIdent = $this->domxml->create_element("item");
00368                 $qtiIdent->set_attribute("ident", "il_".IL_INST_ID."_qst_".$this->getId());
00369                 $qtiIdent->set_attribute("title", $this->getTitle());
00370                 $root->append_child($qtiIdent);
00371                 // add question description
00372                 $qtiComment = $this->domxml->create_element("qticomment");
00373                 $qtiCommentText = $this->domxml->create_text_node($this->getComment());
00374                 $qtiComment->append_child($qtiCommentText);
00375                 $qtiIdent->append_child($qtiComment);
00376                 // add estimated working time
00377                 $qtiDuration = $this->domxml->create_element("duration");
00378                 $workingtime = $this->getEstimatedWorkingTime();
00379                 $qtiDurationText = $this->domxml->create_text_node(sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]));
00380                 $qtiDuration->append_child($qtiDurationText);
00381                 $qtiIdent->append_child($qtiDuration);
00382                 // add ILIAS specific metadata
00383                 $qtiItemmetadata = $this->domxml->create_element("itemmetadata");
00384                 $qtiMetadata = $this->domxml->create_element("qtimetadata");
00385                 
00386                 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00387                 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00388                 $qtiFieldlabelText = $this->domxml->create_text_node("ILIAS_VERSION");
00389                 $qtiFieldlabel->append_child($qtiFieldlabelText);
00390                 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00391                 $qtiFieldentryText = $this->domxml->create_text_node($this->ilias->getSetting("ilias_version"));
00392                 $qtiFieldentry->append_child($qtiFieldentryText);
00393                 $qtiMetadatafield->append_child($qtiFieldlabel);
00394                 $qtiMetadatafield->append_child($qtiFieldentry);
00395                 $qtiMetadata->append_child($qtiMetadatafield);
00396 
00397                 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00398                 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00399                 $qtiFieldlabelText = $this->domxml->create_text_node("QUESTIONTYPE");
00400                 $qtiFieldlabel->append_child($qtiFieldlabelText);
00401                 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00402                 $qtiFieldentryText = $this->domxml->create_text_node(ORDERING_QUESTION_IDENTIFIER);
00403                 $qtiFieldentry->append_child($qtiFieldentryText);
00404                 $qtiMetadatafield->append_child($qtiFieldlabel);
00405                 $qtiMetadatafield->append_child($qtiFieldentry);
00406                 $qtiMetadata->append_child($qtiMetadatafield);
00407                 
00408                 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00409                 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00410                 $qtiFieldlabelText = $this->domxml->create_text_node("AUTHOR");
00411                 $qtiFieldlabel->append_child($qtiFieldlabelText);
00412                 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00413                 $qtiFieldentryText = $this->domxml->create_text_node($this->getAuthor());
00414                 $qtiFieldentry->append_child($qtiFieldentryText);
00415                 $qtiMetadatafield->append_child($qtiFieldlabel);
00416                 $qtiMetadatafield->append_child($qtiFieldentry);
00417                 $qtiMetadata->append_child($qtiMetadatafield);
00418                 
00419                 $qtiItemmetadata->append_child($qtiMetadata);
00420                 $qtiIdent->append_child($qtiItemmetadata);
00421                 
00422                 // PART I: qti presentation
00423                 $qtiPresentation = $this->domxml->create_element("presentation");
00424                 $qtiPresentation->set_attribute("label", $this->getTitle());
00425                 // add flow to presentation
00426                 $qtiFlow = $this->domxml->create_element("flow");
00427                 // add material with question text to presentation
00428                 $qtiMaterial = $this->domxml->create_element("material");
00429                 $qtiMatText = $this->domxml->create_element("mattext");
00430                 $qtiMatTextText = $this->domxml->create_text_node($this->get_question());
00431                 $qtiMatText->append_child($qtiMatTextText);
00432                 $qtiMaterial->append_child($qtiMatText);
00433                 $qtiFlow->append_child($qtiMaterial);
00434                 // add answers to presentation
00435                 $qtiResponseLid = $this->domxml->create_element("response_lid");
00436                 if ($this->get_ordering_type() == OQ_PICTURES)
00437                 {
00438                         $qtiResponseLid->set_attribute("ident", "OQP");
00439                         $qtiResponseLid->set_attribute("rcardinality", "Ordered");
00440                         if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
00441                         {
00442                                 $qtiResponseLid->set_attribute("output", "javascript");
00443                         }
00444                 }
00445                         else
00446                 {
00447                         $qtiResponseLid->set_attribute("ident", "OQT");
00448                         $qtiResponseLid->set_attribute("rcardinality", "Ordered");
00449                         if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
00450                         {
00451                                 $qtiResponseLid->set_attribute("output", "javascript");
00452                         }
00453                 }
00454                 $solution = $this->getSuggestedSolution(0);
00455                 if (count($solution))
00456                 {
00457                         if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00458                         {
00459                                 $qtiMaterial = $this->domxml->create_element("material");
00460                                 $qtiMaterial->set_attribute("label", "suggested_solution");
00461                                 $qtiMatText = $this->domxml->create_element("mattext");
00462                                 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00463                                 if (strcmp($matches[1], "") != 0)
00464                                 {
00465                                         $intlink = $solution["internal_link"];
00466                                 }
00467                                 $qtiMatTextText = $this->domxml->create_text_node($intlink);
00468                                 $qtiMatText->append_child($qtiMatTextText);
00469                                 $qtiMaterial->append_child($qtiMatText);
00470                                 $qtiResponseLid->append_child($qtiMaterial);
00471                         }
00472                 }
00473                 $qtiRenderChoice = $this->domxml->create_element("render_choice");
00474                 // shuffle output
00475                 if ($this->getShuffle())
00476                 {
00477                         $qtiRenderChoice->set_attribute("shuffle", "Yes");
00478                 }
00479                 else
00480                 {
00481                         $qtiRenderChoice->set_attribute("shuffle", "No");
00482                 }
00483 
00484                 // shuffle
00485                 $akeys = array_keys($this->answers);
00486                 if ($this->getshuffle() && $a_shuffle)
00487                 {
00488                         $akeys = $this->pcArrayShuffle($akeys);
00489                 }
00490 
00491                 // add answers
00492                 foreach ($akeys as $index)
00493                 {
00494                         $answer = $this->answers[$index];
00495 
00496                         $qtiResponseLabel = $this->domxml->create_element("response_label");
00497                         $qtiResponseLabel->set_attribute("ident", $index);
00498                         $qtiMaterial = $this->domxml->create_element("material");
00499                         if ($this->get_ordering_type() == OQ_PICTURES)
00500                         {
00501                                 $qtiMatImage = $this->domxml->create_element("matimage");
00502                                 $imagetype = "image/jpeg";
00503                                 if (preg_match("/.*\.(png|gif)$/", $answer->get_answertext(), $matches))
00504                                 {
00505                                         $imagetype = "image/".$matches[1];
00506                                 }
00507                                 $qtiMatImage->set_attribute("imagtype", $imagetype);
00508                                 $qtiMatImage->set_attribute("label", $answer->get_answertext());
00509                                 if ($test_output)
00510                                 {
00511                                         $qtiMatImage->set_attribute("uri", $this->getImagePathWeb() . $answer->get_answertext());
00512                                 }
00513                                 else
00514                                 {
00515                                         $qtiMatImage->set_attribute("embedded", "base64");
00516                                         $imagepath = $this->getImagePath() . $answer->get_answertext();
00517                                         $fh = fopen($imagepath, "rb");
00518                                         if ($fh == false)
00519                                         {
00520                                                 //global $ilErr;
00521                                                 //$ilErr->raiseError($this->lng->txt("error_open_image_file"), $ilErr->MESSAGE);
00522                                                 //return;
00523                                         }
00524                                         else
00525                                         {
00526                                                 $imagefile = fread($fh, filesize($imagepath));
00527                                                 fclose($fh);
00528                                                 $base64 = base64_encode($imagefile);
00529                                                 $qtiBase64Data = $this->domxml->create_text_node($base64);
00530                                                 $qtiMatImage->append_child($qtiBase64Data);
00531                                         }
00532                                 }
00533                                 $qtiMaterial->append_child($qtiMatImage);
00534                         }
00535                         else
00536                         {
00537                                 $qtiMatText = $this->domxml->create_element("mattext");
00538                                 $qtiMatTextText = $this->domxml->create_text_node($answer->get_answertext());
00539                                 $qtiMatText->append_child($qtiMatTextText);
00540                                 $qtiMaterial->append_child($qtiMatText);
00541                         }
00542                         $qtiResponseLabel->append_child($qtiMaterial);
00543                         $qtiRenderChoice->append_child($qtiResponseLabel);
00544                 }
00545                 $qtiResponseLid->append_child($qtiRenderChoice);
00546                 $qtiFlow->append_child($qtiResponseLid);
00547                 $qtiPresentation->append_child($qtiFlow);
00548                 $qtiIdent->append_child($qtiPresentation);
00549 
00550                 // PART II: qti resprocessing
00551                 $qtiResprocessing = $this->domxml->create_element("resprocessing");
00552                 $qtiOutcomes = $this->domxml->create_element("outcomes");
00553                 $qtiDecvar = $this->domxml->create_element("decvar");
00554                 $qtiOutcomes->append_child($qtiDecvar);
00555                 $qtiResprocessing->append_child($qtiOutcomes);
00556                 // add response conditions
00557                 foreach ($this->answers as $index => $answer)
00558                 {
00559                         $qtiRespcondition = $this->domxml->create_element("respcondition");
00560                         $qtiRespcondition->set_attribute("continue", "Yes");
00561                         // qti conditionvar
00562                         $qtiConditionvar = $this->domxml->create_element("conditionvar");
00563                         $qtiVarequal = $this->domxml->create_element("varequal");
00564                         if ($this->get_ordering_type() == OQ_PICTURES)
00565                         {
00566                                 $qtiVarequal->set_attribute("respident", "OQP");
00567                         }
00568                                 else
00569                         {
00570                                 $qtiVarequal->set_attribute("respident", "OQT");
00571                         }
00572                         $qtiVarequal->set_attribute("index", $answer->get_solution_order());
00573                         $qtiVarequalText = $this->domxml->create_text_node($index);
00574                         $qtiVarequal->append_child($qtiVarequalText);
00575                         $qtiConditionvar->append_child($qtiVarequal);
00576                         // qti setvar
00577                         $qtiSetvar = $this->domxml->create_element("setvar");
00578                         $qtiSetvar->set_attribute("action", "Add");
00579                         $qtiSetvarText = $this->domxml->create_text_node($answer->get_points());
00580                         $qtiSetvar->append_child($qtiSetvarText);
00581                         // qti displayfeedback
00582                         $qtiDisplayfeedback = $this->domxml->create_element("displayfeedback");
00583                         $qtiDisplayfeedback->set_attribute("feedbacktype", "Response");
00584                         $qtiDisplayfeedback->set_attribute("linkrefid", "link_$index");
00585                         $qtiRespcondition->append_child($qtiConditionvar);
00586                         $qtiRespcondition->append_child($qtiSetvar);
00587                         $qtiRespcondition->append_child($qtiDisplayfeedback);
00588                         $qtiResprocessing->append_child($qtiRespcondition);
00589                 }
00590                 $qtiIdent->append_child($qtiResprocessing);
00591 
00592                 // PART III: qti itemfeedback
00593                 foreach ($this->answers as $index => $answer)
00594                 {
00595                         $qtiItemfeedback = $this->domxml->create_element("itemfeedback");
00596                         $qtiItemfeedback->set_attribute("ident", "link_$index");
00597                         $qtiItemfeedback->set_attribute("view", "All");
00598                         // qti flow_mat
00599                         $qtiFlowmat = $this->domxml->create_element("flow_mat");
00600                         $qtiMaterial = $this->domxml->create_element("material");
00601                         $qtiMattext = $this->domxml->create_element("mattext");
00602                         // Insert response text for right/wrong answers here!!!
00603                         $qtiMattextText = $this->domxml->create_text_node("");
00604                         $qtiMattext->append_child($qtiMattextText);
00605                         $qtiMaterial->append_child($qtiMattext);
00606                         $qtiFlowmat->append_child($qtiMaterial);
00607                         $qtiItemfeedback->append_child($qtiFlowmat);
00608                         $qtiIdent->append_child($qtiItemfeedback);
00609                 }
00610 
00611                 $xml = $this->domxml->dump_mem(true);
00612                 if (!$a_include_header)
00613                 {
00614                         $pos = strpos($xml, "?>");
00615                         $xml = substr($xml, $pos + 2);
00616                 }
00617 //echo htmlentities($xml);
00618                 return $xml;
00619 
00620         }
00621 
00622 
00631         function saveToDb($original_id = "")
00632         {
00633                 global $ilias;
00634 
00635                 $db =& $ilias->db;
00636                 $complete = 0;
00637                 if ($this->isComplete())
00638                 {
00639                         $complete = 1;
00640                 }
00641 
00642                 $estw_time = $this->getEstimatedWorkingTime();
00643                 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00644 
00645                 if ($original_id)
00646                 {
00647                         $original_id = $db->quote($original_id);
00648                 }
00649                 else
00650                 {
00651                         $original_id = "NULL";
00652                 }
00653 
00654                 if ($this->id == -1)
00655                 {
00656                         // Neuen Datensatz schreiben
00657                         $now = getdate();
00658                         $question_type = $this->getQuestionType();
00659                         $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00660                         $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, working_time, ordering_type, points, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00661                                 $db->quote($question_type . ""),
00662                                 $db->quote($this->obj_id . ""),
00663                                 $db->quote($this->title . ""),
00664                                 $db->quote($this->comment . ""),
00665                                 $db->quote($this->author . ""),
00666                                 $db->quote($this->owner . ""),
00667                                 $db->quote($this->question . ""),
00668                                 $db->quote($estw_time . ""),
00669                                 $db->quote($this->ordering_type . ""),
00670                                 $db->quote($this->getMaximumPoints() . ""),
00671                                 $db->quote($complete . ""),
00672                                 $db->quote($created . ""),
00673                                 $original_id
00674                         );
00675                         $result = $db->query($query);
00676                         if ($result == DB_OK)
00677                         {
00678                                 $this->id = $this->ilias->db->getLastInsertId();
00679 
00680                                 // create page object of question
00681                                 $this->createPageObject();
00682 
00683                                 // Falls die Frage in einen Test eingef�gt werden soll, auch diese Verbindung erstellen
00684                                 if ($this->getTestId() > 0)
00685                                 {
00686                                         $this->insertIntoTest($this->getTestId());
00687                                 }
00688                         }
00689                 }
00690                 else
00691                 {
00692                         // Vorhandenen Datensatz aktualisieren
00693                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, ordering_type = %s, points = %s, complete = %s WHERE question_id = %s",
00694                                 $db->quote($this->obj_id. ""),
00695                                 $db->quote($this->title . ""),
00696                                 $db->quote($this->comment . ""),
00697                                 $db->quote($this->author . ""),
00698                                 $db->quote($this->question . ""),
00699                                 $db->quote($estw_time . ""),
00700                                 $db->quote($this->ordering_type . ""),
00701                                 $db->quote($this->getMaximumPoints() . ""),
00702                                 $db->quote($complete . ""),
00703                                 $db->quote($this->id . "")
00704                         );
00705                         $result = $db->query($query);
00706                 }
00707                 if ($result == DB_OK)
00708                 {
00709                         // Antworten schreiben
00710                         // alte Antworten löschen
00711                         $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
00712                                 $db->quote($this->id)
00713                         );
00714                         $result = $db->query($query);
00715 
00716                         // Anworten wegschreiben
00717                         foreach ($this->answers as $key => $value)
00718                         {
00719                                 $answer_obj = $this->answers[$key];
00720                                 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, solution_order, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
00721                                         $db->quote($this->id),
00722                                         $db->quote($answer_obj->get_answertext() . ""),
00723                                         $db->quote($answer_obj->get_points() . ""),
00724                                         $db->quote($answer_obj->get_order() . ""),
00725                                         $db->quote($answer_obj->get_solution_order() . "")
00726                                 );
00727                                 $answer_result = $db->query($query);
00728                         }
00729                 }
00730                 parent::saveToDb($original_id);
00731         }
00732 
00742         function loadFromDb($question_id)
00743         {
00744                 global $ilias;
00745                 $db =& $ilias->db;
00746 
00747                 $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
00748                         $db->quote($question_id)
00749                 );
00750                 $result = $db->query($query);
00751                 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00752                 {
00753                         if ($result->numRows() == 1)
00754                         {
00755                                 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00756                                 $this->id = $question_id;
00757                                 $this->title = $data->title;
00758                                 $this->obj_id = $data->obj_fi;
00759                                 $this->comment = $data->comment;
00760                                 $this->original_id = $data->original_id;
00761                                 $this->author = $data->author;
00762                                 $this->owner = $data->owner;
00763                                 $this->question = $data->question_text;
00764                                 $this->solution_hint = $data->solution_hint;
00765                                 $this->ordering_type = $data->ordering_type;
00766                                 $this->points = $data->points;
00767                                 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00768                         }
00769 
00770                         $query = sprintf("SELECT * FROM qpl_answers WHERE question_fi = %s ORDER BY aorder ASC",
00771                                 $db->quote($question_id)
00772                         );
00773                         $result = $db->query($query);
00774                         if (strcmp(strtolower(get_class($result)), db_result) == 0)
00775                         {
00776                                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00777                                 {
00778                                         array_push($this->answers, new ASS_AnswerOrdering($data->answertext, $data->points, $data->aorder, $data->solution_order));
00779                                 }
00780                         }
00781                 }
00782                 parent::loadFromDb($question_id);
00783         }
00784 
00792         function addAnswer($answertext, $points, $answerorder, $solutionorder)
00793         {
00794                 array_push($this->answers, new ASS_AnswerOrdering($answertext, $points, $answerorder, $solutionorder));
00795         }
00796         
00804         function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00805         {
00806                 if ($this->id <= 0)
00807                 {
00808                         // The question has not been saved. It cannot be duplicated
00809                         return;
00810                 }
00811                 // duplicate the question in database
00812                 $clone = $this;
00813                 include_once ("./assessment/classes/class.assQuestion.php");
00814                 $original_id = ASS_Question::_getOriginalId($this->id);
00815                 $clone->id = -1;
00816                 if ($title)
00817                 {
00818                         $clone->setTitle($title);
00819                 }
00820                 if ($author)
00821                 {
00822                         $clone->setAuthor($author);
00823                 }
00824                 if ($owner)
00825                 {
00826                         $clone->setOwner($owner);
00827                 }
00828                 if ($for_test)
00829                 {
00830                         $clone->saveToDb($original_id);
00831                 }
00832                 else
00833                 {
00834                         $clone->saveToDb();
00835                 }
00836 
00837                 // copy question page content
00838                 $clone->copyPageOfQuestion($original_id);
00839 
00840                 // duplicate the image
00841                 $clone->duplicateImages($original_id);
00842                 return $clone->id;
00843         }
00844 
00845         function duplicateImages($question_id)
00846         {
00847                 if ($this->get_ordering_type() == OQ_PICTURES)
00848                 {
00849                         $imagepath = $this->getImagePath();
00850                         $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00851                         if (!file_exists($imagepath)) {
00852                                 ilUtil::makeDirParents($imagepath);
00853                         }
00854                         foreach ($this->answers as $answer)
00855                         {
00856                                 $filename = $answer->get_answertext();
00857                                 if (!copy($imagepath_original . $filename, $imagepath . $filename)) {
00858                                         print "image could not be duplicated!!!! ";
00859                                 }
00860                                 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg")) {
00861                                         print "image thumbnail could not be duplicated!!!! ";
00862                                 }
00863                         }
00864                 }
00865         }
00866 
00876         function set_question($question = "")
00877         {
00878                 $this->question = $question;
00879         }
00880 
00890         function set_ordering_type($ordering_type = OQ_TERMS)
00891         {
00892                 $this->ordering_type = $ordering_type;
00893         }
00894 
00904         function get_question()
00905         {
00906                 return $this->question;
00907         }
00908 
00918         function get_ordering_type()
00919         {
00920                 return $this->ordering_type;
00921         }
00922 
00938         function add_answer(
00939                 $answertext = "",
00940                 $points = 0.0,
00941                 $order = 0,
00942                 $solution_order = 0
00943         )
00944         {
00945                 $found = -1;
00946                 foreach ($this->answers as $key => $value)
00947                 {
00948                         if ($value->get_order() == $order)
00949                         {
00950                                 $found = $order;
00951                         }
00952                 }
00953                 if ($found >= 0)
00954                 {
00955                         // Antwort einfügen
00956                         $answer = new ASS_AnswerOrdering($answertext, $points, $found, $solution_order);
00957                         array_push($this->answers, $answer);
00958                         for ($i = $found + 1; $i < count($this->answers); $i++)
00959                         {
00960                                 $this->answers[$i] = $this->answers[$i-1];
00961                         }
00962                         $this->answers[$found] = $answer;
00963                 }
00964                 else
00965                 {
00966                         // Anwort anhängen
00967                         $answer = new ASS_AnswerOrdering($answertext, $points,
00968                                 count($this->answers), $solution_order);
00969                         array_push($this->answers, $answer);
00970                 }
00971         }
00972 
00984         function get_answer($index = 0)
00985         {
00986                 if ($index < 0) return NULL;
00987                 if (count($this->answers) < 1) return NULL;
00988                 if ($index >= count($this->answers)) return NULL;
00989                 return $this->answers[$index];
00990         }
00991 
01002         function delete_answer($index = 0)
01003         {
01004                 if ($index < 0)
01005                 {
01006                         return;
01007                 }
01008                 if (count($this->answers) < 1)
01009                 {
01010                         return;
01011                 }
01012                 if ($index >= count($this->answers))
01013                 {
01014                         return;
01015                 }
01016                 unset($this->answers[$index]);
01017                 $this->answers = array_values($this->answers);
01018                 for ($i = 0; $i < count($this->answers); $i++)
01019                 {
01020                         if ($this->answers[$i]->get_order() > $index)
01021                         {
01022                                 $this->answers[$i]->set_order($i);
01023                         }
01024                 }
01025         }
01026 
01035         function flush_answers()
01036         {
01037                 $this->answers = array();
01038         }
01039 
01049         function get_answer_count()
01050         {
01051                 return count($this->answers);
01052         }
01053 
01062         function get_max_solution_order()
01063         {
01064                 if (count($this->answers) == 0)
01065                 {
01066                         $max = 0;
01067                 }
01068                 else
01069                 {
01070                         $max = $this->answers[0]->get_solution_order();
01071                 }
01072                 foreach ($this->answers as $key => $value)
01073                 {
01074                         if ($value->get_solution_order() > $max)
01075                         {
01076                                 $max = $value->get_solution_order();
01077                         }
01078                 }
01079                 return $max;
01080         }
01081 
01093         function calculateReachedPoints($user_id, $test_id)
01094         {
01095                 global $ilDB;
01096                 
01097                 $found_value1 = array();
01098                 $found_value2 = array();
01099                 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01100                         $ilDB->quote($user_id),
01101                         $ilDB->quote($test_id),
01102                         $ilDB->quote($this->getId())
01103                 );
01104                 $result = $ilDB->query($query);
01105                 $user_order = array();
01106                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01107                 {
01108                         if ((strcmp($data->value1, "") != 0) && (strcmp($data->value2, "") != 0))
01109                         {
01110                                 $user_order[$data->value2] = $data->value1;
01111                         }
01112                 }
01113                 ksort($user_order);
01114                 $user_order = array_values($user_order);
01115                 $answer_order = array();
01116                 foreach ($this->answers as $key => $answer)
01117                 {
01118                         $answer_order[$answer->get_solution_order()] = $key;
01119                 }
01120                 ksort($answer_order);
01121                 $answer_order = array_values($answer_order);
01122                 $points = 0;
01123                 foreach ($answer_order as $index => $answer_id)
01124                 {
01125                         if (strcmp($user_order[$index], "") != 0)
01126                         {
01127                                 if ($answer_id == $user_order[$index])
01128                                 {
01129                                         $points += $this->answers[$answer_id]->get_points();
01130                                 }
01131                         }
01132                 }
01133 
01134                 // check for special scoring options in test
01135                 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
01136                         $ilDB->quote($test_id)
01137                 );
01138                 $result = $ilDB->query($query);
01139                 if ($result->numRows() == 1)
01140                 {
01141                         $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
01142                         if ($row["count_system"] == 1)
01143                         {
01144                                 if ($points != $this->getMaximumPoints())
01145                                 {
01146                                         $points = 0;
01147                                 }
01148                         }
01149                 }
01150                 else
01151                 {
01152                         $points = 0;
01153                 }
01154                 return $points;
01155         }
01156 
01166         function getReachedInformation($user_id, $test_id)
01167         {
01168                 $found_value1 = array();
01169                 $found_value2 = array();
01170                 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01171                         $this->ilias->db->quote($user_id),
01172                         $this->ilias->db->quote($test_id),
01173                         $this->ilias->db->quote($this->getId())
01174                 );
01175                 $result = $this->ilias->db->query($query);
01176                 $user_result = array();
01177                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01178                 {
01179                         $solution = array(
01180                                 "answer_id" => $data->value1,
01181                                 "order" => $data->value2
01182                         );
01183                         $user_result[$data->value1] = $solution;
01184                 }
01185                 return $user_result;
01186         }
01187 
01196         function getMaximumPoints()
01197         {
01198                 $points = 0;
01199                 foreach ($this->answers as $key => $value)
01200                 {
01201                         $points += $value->get_points();
01202                 }
01203                 return $points;
01204         }
01205 
01216         function set_image_file($image_filename, $image_tempfilename = "")
01217         {
01218                 $result = 0;
01219                 if (!empty($image_tempfilename))
01220                 {
01221                         $image_filename = str_replace(" ", "_", $image_filename);
01222                         $imagepath = $this->getImagePath();
01223                         if (!file_exists($imagepath))
01224                         {
01225                                 ilUtil::makeDirParents($imagepath);
01226                         }
01227                         if (!ilUtil::moveUploadedFile($image_tempfilename,$image_filename, $imagepath.$image_filename))
01228                         {
01229                                 $result = 2;
01230                         }
01231                         else
01232                         {
01233                                 require_once "./content/classes/Media/class.ilObjMediaObject.php";
01234                                 $mimetype = ilObjMediaObject::getMimeType($imagepath . $image_filename);
01235                                 if (!preg_match("/^image/", $mimetype))
01236                                 {
01237                                         unlink($imagepath . $image_filename);
01238                                         $result = 1;
01239                                 }
01240                                 else
01241                                 {
01242                                         // create thumbnail file
01243                                         $thumbpath = $imagepath . $image_filename . "." . "thumb.jpg";
01244                                         ilUtil::convertImage($imagepath.$image_filename, $thumbpath, strtoupper($extension), 100);
01245                                 }
01246                         }
01247                 }
01248                 return $result;
01249         }
01250 
01260         function checkSaveData()
01261         {
01262                 $result = true;
01263                 $order_values = array();
01264                 foreach ($_POST as $key => $value)
01265                 {
01266                         if (preg_match("/^order_(\d+)/", $key, $matches))
01267                         {
01268                                 if (strcmp($value, "") != 0)
01269                                 {
01270                                         array_push($order_values, $value);
01271                                 }
01272                         }
01273                 }
01274                 $check_order = array_flip($order_values);
01275                 if (count($check_order) != count($order_values))
01276                 {
01277                         // duplicate order values!!!
01278                         $result = false;
01279                         sendInfo($this->lng->txt("duplicate_order_values_entered"));
01280                 }
01281                 return $result;
01282         }
01283 
01294         function saveWorkingData($test_id, $limit_to = LIMIT_NO_LIMIT)
01295         {
01296                 global $ilDB;
01297                 global $ilUser;
01298 
01299                 $saveWorkingDataResult = $this->checkSaveData();
01300                 if ($saveWorkingDataResult)
01301                 {
01302                         $db =& $ilDB->db;
01303         
01304                         $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01305                                 $db->quote($ilUser->id),
01306                                 $db->quote($test_id),
01307                                 $db->quote($this->getId())
01308                         );
01309                         $result = $db->query($query);
01310         
01311                         foreach ($_POST as $key => $value)
01312                         {
01313                                 if (preg_match("/^order_(\d+)/", $key, $matches))
01314                                 {
01315                                         if (!(preg_match("/initial_value_\d+/", $value)))
01316                                         {
01317                                                 $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)",
01318                                                         $db->quote($ilUser->id),
01319                                                         $db->quote($test_id),
01320                                                         $db->quote($this->getId()),
01321                                                         $db->quote($matches[1]),
01322                                                         $db->quote($value)
01323                                                 );
01324                                                 $result = $db->query($query);
01325                                         }
01326                                 }
01327                         }
01328                 }
01329     parent::saveWorkingData($test_id);
01330                 return $saveWorkingDataResult;
01331         }
01332 
01333         function syncWithOriginal()
01334         {
01335                 global $ilias;
01336                 if ($this->original_id)
01337                 {
01338                         $complete = 0;
01339                         if ($this->isComplete())
01340                         {
01341                                 $complete = 1;
01342                         }
01343                         $db = & $ilias->db;
01344         
01345                         $estw_time = $this->getEstimatedWorkingTime();
01346                         $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01347         
01348                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, ordering_type = %s, points = %s, complete = %s WHERE question_id = %s",
01349                                 $db->quote($this->obj_id. ""),
01350                                 $db->quote($this->title . ""),
01351                                 $db->quote($this->comment . ""),
01352                                 $db->quote($this->author . ""),
01353                                 $db->quote($this->question . ""),
01354                                 $db->quote($estw_time . ""),
01355                                 $db->quote($this->ordering_type . ""),
01356                                 $db->quote($this->getMaximumPoints() . ""),
01357                                 $db->quote($complete . ""),
01358                                 $db->quote($this->original_id . "")
01359                         );
01360                         $result = $db->query($query);
01361 
01362                         if ($result == DB_OK)
01363                         {
01364                                 // write ansers
01365                                 // delete old answers
01366                                 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
01367                                         $db->quote($this->original_id)
01368                                 );
01369                                 $result = $db->query($query);
01370         
01371                                 foreach ($this->answers as $key => $value)
01372                                 {
01373                                         $answer_obj = $this->answers[$key];
01374                                         $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, solution_order, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
01375                                                 $db->quote($this->original_id . ""),
01376                                                 $db->quote($answer_obj->get_answertext() . ""),
01377                                                 $db->quote($answer_obj->get_points() . ""),
01378                                                 $db->quote($answer_obj->get_order() . ""),
01379                                                 $db->quote($answer_obj->get_solution_order() . "")
01380                                         );
01381                                         $answer_result = $db->query($query);
01382                                 }
01383                         }
01384                         parent::syncWithOriginal();
01385                 }
01386         }
01387 
01388         function pc_array_shuffle($array) {
01389                 mt_srand((double)microtime()*1000000);
01390                 $i = count($array);
01391                 while(--$i) 
01392                 {
01393                         $j = mt_rand(0, $i);
01394                         if ($i != $j) 
01395                         {
01396                                 // swap elements
01397                                 $tmp = $array[$j];
01398                                 $array[$j] = $array[$i];
01399                                 $array[$i] = $tmp;
01400                         }
01401                 }
01402                 return $array;
01403         }
01404         
01405         function createRandomSolution($test_id, $user_id)
01406         {
01407                 global $ilDB;
01408                 global $ilUser;
01409 
01410                 $db =& $ilDB->db;
01411 
01412                 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01413                         $db->quote($user_id),
01414                         $db->quote($test_id),
01415                         $db->quote($this->getId())
01416                 );
01417                 $result = $db->query($query);
01418 
01419                 $orders = range(1, count($this->answers));
01420                 $orders = $this->pc_array_shuffle($orders);
01421                 foreach ($this->answers as $key => $value)
01422                 {
01423                         $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)",
01424                                 $db->quote($user_id),
01425                                 $db->quote($test_id),
01426                                 $db->quote($this->getId()),
01427                                 $db->quote($key),
01428                                 $db->quote(array_pop($orders))
01429                         );
01430                         $result = $db->query($query);
01431                 }
01432         }
01433 
01442         function getQuestionType()
01443         {
01444                 return 5;
01445         }
01446 }
01447 
01448 ?>

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