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

assessment/classes/class.assMultipleChoice.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 require_once "./assessment/classes/class.assQuestion.php";
00024 require_once "./assessment/classes/class.assAnswerBinaryState.php";
00025 require_once "./assessment/classes/class.ilQTIUtils.php";
00026 
00027 define("RESPONSE_SINGLE", "0");
00028 define("RESPONSE_MULTIPLE", "1");
00029 
00030 define("OUTPUT_ORDER", "0");
00031 define("OUTPUT_RANDOM", "1");
00032 
00033 define("MULTIPLE_CHOICE_QUESTION_IDENTIFIER", "MULTIPLE CHOICE QUESTION");
00034 
00046 class ASS_MultipleChoice extends ASS_Question
00047 {
00055         var $question;
00056 
00064         var $answers;
00065 
00074         var $response;
00075 
00084         var $output_type;
00085 
00101         function ASS_MultipleChoice(
00102                 $title = "",
00103                 $comment = "",
00104                 $author = "",
00105                 $owner = -1,
00106                 $question = "",
00107                 $response = RESPONSE_SINGLE,
00108                 $output_type = OUTPUT_ORDER
00109           )
00110         {
00111                 $this->ASS_Question($title, $comment, $author, $owner);
00112                 $this->question = $question;
00113                 $this->response = $response;
00114                 $this->output_type = $output_type;
00115                 $this->answers = array();
00116         }
00117 
00126         function isComplete()
00127         {
00128                 if (($this->title) and ($this->author) and ($this->question) and (count($this->answers)))
00129                 {
00130                         return true;
00131                 }
00132                         else
00133                 {
00134                         return false;
00135                 }
00136         }
00137 
00147         function from_xml($xml_text)
00148         {
00149                 $result = false;
00150                 if (!empty($this->domxml))
00151                 {
00152                         $this->domxml->free();
00153                 }
00154                 $xml_text = preg_replace("/>\s*?</", "><", $xml_text);
00155                 $this->domxml = domxml_open_mem($xml_text);
00156                 if (!empty($this->domxml))
00157                 {
00158                         $root = $this->domxml->document_element();
00159                         $item = $root->first_child();
00160                         $this->setTitle($item->get_attribute("title"));
00161                         $this->gaps = array();
00162                         $itemnodes = $item->child_nodes();
00163                         foreach ($itemnodes as $index => $node)
00164                         {
00165                                 switch ($node->node_name())
00166                                 {
00167                                         case "qticomment":
00168                                                 $comment = $node->get_content();
00169                                                 if (strpos($comment, "ILIAS Version=") !== false)
00170                                                 {
00171                                                 }
00172                                                 elseif (strpos($comment, "Questiontype=") !== false)
00173                                                 {
00174                                                 }
00175                                                 elseif (strpos($comment, "Author=") !== false)
00176                                                 {
00177                                                         $comment = str_replace("Author=", "", $comment);
00178                                                         $this->setAuthor($comment);
00179                                                 }
00180                                                 else
00181                                                 {
00182                                                         $this->setComment($comment);
00183                                                 }
00184                                                 break;
00185                                         case "itemmetadata":
00186                                                 $md_array = array();
00187                                                 $metanodes = $node->child_nodes();
00188                                                 foreach ($metanodes as $metanode)
00189                                                 {
00190                                                         switch ($metanode->node_name())
00191                                                         {
00192                                                                 case "qtimetadata":
00193                                                                         $metafields = $metanode->child_nodes();
00194                                                                         foreach ($metafields as $metafield)
00195                                                                         {
00196                                                                                 switch ($metafield->node_name())
00197                                                                                 {
00198                                                                                         case "qtimetadatafield":
00199                                                                                                 $metafieldlist = $metafield->child_nodes();
00200                                                                                                 $md = array("label" => "", "entry" => "");
00201                                                                                                 foreach ($metafieldlist as $attr)
00202                                                                                                 {
00203                                                                                                         switch ($attr->node_name())
00204                                                                                                         {
00205                                                                                                                 case "fieldlabel":
00206                                                                                                                         $md["label"] = $attr->get_content();
00207                                                                                                                         break;
00208                                                                                                                 case "fieldentry":
00209                                                                                                                         $md["entry"] = $attr->get_content();
00210                                                                                                                         break;
00211                                                                                                         }
00212                                                                                                 }
00213                                                                                                 array_push($md_array, $md);
00214                                                                                                 break;
00215                                                                                 }
00216                                                                         }
00217                                                                         break;
00218                                                         }
00219                                                 }
00220                                                 foreach ($md_array as $md)
00221                                                 {
00222                                                         switch ($md["label"])
00223                                                         {
00224                                                                 case "ILIAS_VERSION":
00225                                                                         break;
00226                                                                 case "QUESTIONTYPE":
00227                                                                         break;
00228                                                                 case "AUTHOR":
00229                                                                         $this->setAuthor($md["entry"]);
00230                                                                         break;
00231                                                         }
00232                                                 }
00233                                                 break;
00234                                         case "duration":
00235                                                 $iso8601period = $node->get_content();
00236                                                 if (preg_match("/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches))
00237                                                 {
00238                                                         $this->setEstimatedWorkingTime($matches[4], $matches[5], $matches[6]);
00239                                                 }
00240                                                 break;
00241                                         case "presentation":
00242                                                 $flow = $node->first_child();
00243                                                 $flownodes = $flow->child_nodes();
00244                                                 foreach ($flownodes as $idx => $flownode)
00245                                                 {
00246                                                         if (strcmp($flownode->node_name(), "material") == 0)
00247                                                         {
00248                                                                 $mattext = $flownode->first_child();
00249                                                                 $this->set_question($mattext->get_content());
00250                                                         }
00251                                                         elseif (strcmp($flownode->node_name(), "response_lid") == 0)
00252                                                         {
00253                                                                 $ident = $flownode->get_attribute("ident");
00254                                                                 if (strcmp($ident, "MCSR") == 0)
00255                                                                 {
00256                                                                         $this->set_response(RESPONSE_SINGLE);
00257                                                                 }
00258                                                                 else
00259                                                                 {
00260                                                                         $this->set_response(RESPONSE_MULTIPLE);
00261                                                                 }
00262                                                                 $shuffle = "";
00263                                                                 
00264                                                                 $subnodes = $flownode->child_nodes();
00265                                                                 foreach ($subnodes as $node_type)
00266                                                                 {
00267                                                                         switch ($node_type->node_name())
00268                                                                         {
00269                                                                                 case "render_choice":
00270                                                                                         $render_choice = $node_type;
00271                                                                                         if (strcmp($render_choice->node_name(), "render_choice") == 0)
00272                                                                                         {
00273                                                                                                 $shuffle = $render_choice->get_attribute("shuffle");
00274                                                                                                 $shuf = 0;
00275                                                                                                 if (strcmp(strtolower($shuffle), "yes") == 0)
00276                                                                                                 {
00277                                                                                                         $shuf = 1;
00278                                                                                                 }
00279                                                                                                 $this->setShuffle($shuf);
00280                                                                                                 $labels = $render_choice->child_nodes();
00281                                                                                                 foreach ($labels as $lidx => $response_label)
00282                                                                                                 {
00283                                                                                                         $material = $response_label->first_child();
00284                                                                                                         $mattext = $material->first_child();
00285                                                                                                         $this->add_answer($mattext->get_content(), 0, 0,  $response_label->get_attribute("ident"));
00286                                                                                                 }
00287                                                                                         }
00288                                                                                         break;
00289                                                                                 case "material":
00290                                                                                         $matlabel = $node_type->get_attribute("label");
00291                                                                                         if (strcmp($matlabel, "suggested_solution") == 0)
00292                                                                                         {
00293                                                                                                 $mattype = $node_type->first_child();
00294                                                                                                 if (strcmp($mattype->node_name(), "mattext") == 0)
00295                                                                                                 {
00296                                                                                                         $suggested_solution = $mattype->get_content();
00297                                                                                                         if ($suggested_solution)
00298                                                                                                         {
00299                                                                                                                 if ($this->getId() < 1)
00300                                                                                                                 {
00301                                                                                                                         $this->saveToDb();
00302                                                                                                                 }
00303                                                                                                                 $this->setSuggestedSolution($suggested_solution, 0, true);
00304                                                                                                         }
00305                                                                                                 }
00306                                                                                         }
00307                                                                                         break;
00308                                                                         }
00309                                                                 }
00310                                                         }
00311                                                 }
00312                                                 break;
00313                                         case "resprocessing":
00314                                                 $resproc_nodes = $node->child_nodes();
00315                                                 foreach ($resproc_nodes as $index => $respcondition)
00316                                                 {
00317                                                         if (strcmp($respcondition->node_name(), "respcondition") == 0)
00318                                                         {
00319                                                                 $respcondition_array =& ilQTIUtils::_getRespcondition($respcondition);
00320                                                                 $found_answer = 0;
00321                                                                 $this->answers[$respcondition_array["conditionvar"]["value"]]->set_points($respcondition_array["setvar"]["points"]);
00322                                                                 if ($respcondition_array["conditionvar"]["selected"])
00323                                                                 {
00324                                                                         $this->answers[$respcondition_array["conditionvar"]["value"]]->setChecked();
00325                                                                 }
00326                                                                 $feedbacks[$respcondition_array["displayfeedback"]["linkrefid"]] = array(
00327                                                                         "type" => $respcondition_array["conditionvar"]["respident"],
00328                                                                         "value" => $respcondition_array["conditionvar"]["value"],
00329                                                                         "not" => $respcondition_array["conditionvar"]["not"],
00330                                                                         "points" => $respcondition_array["setvar"]["points"],
00331                                                                         "feedback" => ""
00332                                                                 );
00333                                                         }
00334                                                 }
00335                                                 break;
00336                                 }
00337                         }
00338                         $result = true;
00339                 }
00340                 return $result;
00341         }
00342 
00352         function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false)
00353         {
00354                 if (!empty($this->domxml))
00355                 {
00356                         $this->domxml->free();
00357                 }
00358                 $xml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
00359                 $xml_header .= "<questestinterop></questestinterop>\n";
00360                 $this->domxml = domxml_open_mem($xml_header);
00361                 $root = $this->domxml->document_element();
00362                 // qti ident
00363                 $qtiIdent = $this->domxml->create_element("item");
00364                 $qtiIdent->set_attribute("ident", "il_".IL_INST_ID."_qst_".$this->getId());
00365                 $qtiIdent->set_attribute("title", $this->getTitle());
00366                 $root->append_child($qtiIdent);
00367                 // add question description
00368                 $qtiComment = $this->domxml->create_element("qticomment");
00369                 $qtiCommentText = $this->domxml->create_text_node($this->getComment());
00370                 $qtiComment->append_child($qtiCommentText);
00371                 $qtiIdent->append_child($qtiComment);
00372                 // add estimated working time
00373                 $qtiDuration = $this->domxml->create_element("duration");
00374                 $workingtime = $this->getEstimatedWorkingTime();
00375                 $qtiDurationText = $this->domxml->create_text_node(sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]));
00376                 $qtiDuration->append_child($qtiDurationText);
00377                 $qtiIdent->append_child($qtiDuration);
00378                 // add ILIAS specific metadata
00379                 $qtiItemmetadata = $this->domxml->create_element("itemmetadata");
00380                 $qtiMetadata = $this->domxml->create_element("qtimetadata");
00381                 
00382                 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00383                 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00384                 $qtiFieldlabelText = $this->domxml->create_text_node("ILIAS_VERSION");
00385                 $qtiFieldlabel->append_child($qtiFieldlabelText);
00386                 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00387                 $qtiFieldentryText = $this->domxml->create_text_node($this->ilias->getSetting("ilias_version"));
00388                 $qtiFieldentry->append_child($qtiFieldentryText);
00389                 $qtiMetadatafield->append_child($qtiFieldlabel);
00390                 $qtiMetadatafield->append_child($qtiFieldentry);
00391                 $qtiMetadata->append_child($qtiMetadatafield);
00392 
00393                 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00394                 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00395                 $qtiFieldlabelText = $this->domxml->create_text_node("QUESTIONTYPE");
00396                 $qtiFieldlabel->append_child($qtiFieldlabelText);
00397                 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00398                 $qtiFieldentryText = $this->domxml->create_text_node(MULTIPLE_CHOICE_QUESTION_IDENTIFIER);
00399                 $qtiFieldentry->append_child($qtiFieldentryText);
00400                 $qtiMetadatafield->append_child($qtiFieldlabel);
00401                 $qtiMetadatafield->append_child($qtiFieldentry);
00402                 $qtiMetadata->append_child($qtiMetadatafield);
00403                 
00404                 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00405                 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00406                 $qtiFieldlabelText = $this->domxml->create_text_node("AUTHOR");
00407                 $qtiFieldlabel->append_child($qtiFieldlabelText);
00408                 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00409                 $qtiFieldentryText = $this->domxml->create_text_node($this->getAuthor());
00410                 $qtiFieldentry->append_child($qtiFieldentryText);
00411                 $qtiMetadatafield->append_child($qtiFieldlabel);
00412                 $qtiMetadatafield->append_child($qtiFieldentry);
00413                 $qtiMetadata->append_child($qtiMetadatafield);
00414                 
00415                 $qtiItemmetadata->append_child($qtiMetadata);
00416                 $qtiIdent->append_child($qtiItemmetadata);
00417                 
00418                 // PART I: qti presentation
00419                 $qtiPresentation = $this->domxml->create_element("presentation");
00420                 $qtiPresentation->set_attribute("label", $this->getTitle());
00421                 // add flow to presentation
00422                 $qtiFlow = $this->domxml->create_element("flow");
00423                 // add material with question text to presentation
00424                 $qtiMaterial = $this->domxml->create_element("material");
00425                 $qtiMatText = $this->domxml->create_element("mattext");
00426                 $qtiMatTextText = $this->domxml->create_text_node($this->get_question());
00427                 $qtiMatText->append_child($qtiMatTextText);
00428                 $qtiMaterial->append_child($qtiMatText);
00429                 $qtiFlow->append_child($qtiMaterial);
00430                 // add answers to presentation
00431                 $qtiResponseLid = $this->domxml->create_element("response_lid");
00432                 if ($this->response == RESPONSE_SINGLE)
00433                 {
00434                         $qtiResponseLid->set_attribute("ident", "MCSR");
00435                         $qtiResponseLid->set_attribute("rcardinality", "Single");
00436                 }
00437                         else
00438                 {
00439                         $qtiResponseLid->set_attribute("ident", "MCMR");
00440                         $qtiResponseLid->set_attribute("rcardinality", "Multiple");
00441                 }
00442                 $solution = $this->getSuggestedSolution(0);
00443                 if (count($solution))
00444                 {
00445                         if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00446                         {
00447                                 $qtiMaterial = $this->domxml->create_element("material");
00448                                 $qtiMaterial->set_attribute("label", "suggested_solution");
00449                                 $qtiMatText = $this->domxml->create_element("mattext");
00450                                 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00451                                 if (strcmp($matches[1], "") != 0)
00452                                 {
00453                                         $intlink = $solution["internal_link"];
00454                                 }
00455                                 $qtiMatTextText = $this->domxml->create_text_node($intlink);
00456                                 $qtiMatText->append_child($qtiMatTextText);
00457                                 $qtiMaterial->append_child($qtiMatText);
00458                                 $qtiResponseLid->append_child($qtiMaterial);
00459                         }
00460                 }
00461                 $qtiRenderChoice = $this->domxml->create_element("render_choice");
00462                 // shuffle output
00463                 if ($this->getShuffle())
00464                 {
00465                         $qtiRenderChoice->set_attribute("shuffle", "Yes");
00466                 }
00467                 else
00468                 {
00469                         $qtiRenderChoice->set_attribute("shuffle", "No");
00470                 }
00471 
00472                 $akeys = array_keys($this->answers);
00473                 if ($this->getshuffle() && $a_shuffle)
00474                 {
00475                         $akeys = $this->pcArrayShuffle($akeys);
00476                 }
00477 
00478                 // add answers
00479                 foreach ($akeys as $index)
00480                 {
00481                         $answer = $this->answers[$index];
00482                         $qtiResponseLabel = $this->domxml->create_element("response_label");
00483                         $qtiResponseLabel->set_attribute("ident", $index);
00484                         $qtiMaterial = $this->domxml->create_element("material");
00485                         $qtiMatText = $this->domxml->create_element("mattext");
00486                         $qtiMatTextText = $this->domxml->create_text_node($answer->get_answertext());
00487                         $qtiMatText->append_child($qtiMatTextText);
00488                         $qtiMaterial->append_child($qtiMatText);
00489                         $qtiResponseLabel->append_child($qtiMaterial);
00490                         $qtiRenderChoice->append_child($qtiResponseLabel);
00491                 }
00492                 $qtiResponseLid->append_child($qtiRenderChoice);
00493                 $qtiFlow->append_child($qtiResponseLid);
00494                 $qtiPresentation->append_child($qtiFlow);
00495                 $qtiIdent->append_child($qtiPresentation);
00496                 // PART II: qti resprocessing
00497                 $qtiResprocessing = $this->domxml->create_element("resprocessing");
00498                 $qtiOutcomes = $this->domxml->create_element("outcomes");
00499                 $qtiDecvar = $this->domxml->create_element("decvar");
00500                 $qtiOutcomes->append_child($qtiDecvar);
00501                 $qtiResprocessing->append_child($qtiOutcomes);
00502                 // add response conditions
00503                 foreach ($this->answers as $index => $answer)
00504                 {
00505                         $qtiRespcondition = $this->domxml->create_element("respcondition");
00506                         $qtiRespcondition->set_attribute("continue", "Yes");
00507                         // qti conditionvar
00508                         $qtiConditionvar = $this->domxml->create_element("conditionvar");
00509                         if (!$answer->isStateSet())
00510                         {
00511                                 $qtinot = $this->domxml->create_element("not");
00512                         }
00513                         $qtiVarequal = $this->domxml->create_element("varequal");
00514                         if ($this->response == RESPONSE_SINGLE)
00515                         {
00516                                 $qtiVarequal->set_attribute("respident", "MCSR");
00517                         }
00518                                 else
00519                         {
00520                                 $qtiVarequal->set_attribute("respident", "MCMR");
00521                         }
00522                         $qtiVarequalText = $this->domxml->create_text_node($index);
00523                         $qtiVarequal->append_child($qtiVarequalText);
00524                         if (!$answer->isStateSet())
00525                         {
00526                                 $qtiConditionvar->append_child($qtinot);
00527                                 $qtinot->append_child($qtiVarequal);
00528                         }
00529                         else
00530                         {
00531                                 $qtiConditionvar->append_child($qtiVarequal);
00532                         }
00533                         // qti setvar
00534                         $qtiSetvar = $this->domxml->create_element("setvar");
00535                         $qtiSetvar->set_attribute("action", "Add");
00536                         $qtiSetvarText = $this->domxml->create_text_node($answer->get_points());
00537                         $qtiSetvar->append_child($qtiSetvarText);
00538                         // qti displayfeedback
00539                         $qtiDisplayfeedback = $this->domxml->create_element("displayfeedback");
00540                         $qtiDisplayfeedback->set_attribute("feedbacktype", "Response");
00541                         $linkrefid = "";
00542                         if ($answer->isStateChecked())
00543                         {
00544                                 if ($this->response == RESPONSE_SINGLE)
00545                                 {
00546                                         $linkrefid = "True";
00547                                 }
00548                                         else
00549                                 {
00550                                         $linkrefid = "True_$index";
00551                                 }
00552                         }
00553                           else
00554                         {
00555                                 $linkrefid = "False_$index";
00556                         }
00557                         $qtiDisplayfeedback->set_attribute("linkrefid", $linkrefid);
00558                         $qtiRespcondition->append_child($qtiConditionvar);
00559                         $qtiRespcondition->append_child($qtiSetvar);
00560                         $qtiRespcondition->append_child($qtiDisplayfeedback);
00561                         $qtiResprocessing->append_child($qtiRespcondition);
00562                 }
00563                 $qtiIdent->append_child($qtiResprocessing);
00564 
00565                 // PART III: qti itemfeedback
00566                 foreach ($this->answers as $index => $answer)
00567                 {
00568                         $qtiItemfeedback = $this->domxml->create_element("itemfeedback");
00569                         $linkrefid = "";
00570                         if ($answer->isStateChecked())
00571                         {
00572                                 if ($this->response == RESPONSE_SINGLE)
00573                                 {
00574                                         $linkrefid = "True";
00575                                 }
00576                                         else
00577                                 {
00578                                         $linkrefid = "True_$index";
00579                                 }
00580                         }
00581                           else
00582                         {
00583                                 $linkrefid = "False_$index";
00584                         }
00585                         $qtiItemfeedback->set_attribute("ident", $linkrefid);
00586                         $qtiItemfeedback->set_attribute("view", "All");
00587                         // qti flow_mat
00588                         $qtiFlowmat = $this->domxml->create_element("flow_mat");
00589                         $qtiMaterial = $this->domxml->create_element("material");
00590                         $qtiMattext = $this->domxml->create_element("mattext");
00591                         // Insert response text for right/wrong answers here!!!
00592                         $qtiMattextText = $this->domxml->create_text_node("");
00593                         $qtiMattext->append_child($qtiMattextText);
00594                         $qtiMaterial->append_child($qtiMattext);
00595                         $qtiFlowmat->append_child($qtiMaterial);
00596                         $qtiItemfeedback->append_child($qtiFlowmat);
00597                         $qtiIdent->append_child($qtiItemfeedback);
00598                 }
00599                 $xml = $this->domxml->dump_mem(true);
00600                 if (!$a_include_header)
00601                 {
00602                         $pos = strpos($xml, "?>");
00603                         $xml = substr($xml, $pos + 2);
00604                 }
00605 //echo htmlentities($xml);
00606                 return $xml;
00607         }
00608 
00617         function saveToDb($original_id = "")
00618         {
00619                 global $ilias;
00620 
00621                 $complete = 0;
00622                 if ($this->isComplete())
00623                 {
00624                         $complete = 1;
00625                 }
00626                 $db = & $ilias->db;
00627 
00628                 $estw_time = $this->getEstimatedWorkingTime();
00629                 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00630 
00631                 if ($original_id)
00632                 {
00633                         $original_id = $db->quote($original_id);
00634                 }
00635                 else
00636                 {
00637                         $original_id = "NULL";
00638                 }
00639 
00640                 if ($this->id == -1)
00641                 {
00642                         // Neuen Datensatz schreiben
00643                         $now = getdate();
00644                         $question_type = $this->getQuestionType();
00645                         $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00646                         $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, points, working_time, shuffle, choice_response, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00647                                 $db->quote($question_type),
00648                                 $db->quote($this->obj_id),
00649                                 $db->quote($this->title),
00650                                 $db->quote($this->comment),
00651                                 $db->quote($this->author),
00652                                 $db->quote($this->owner),
00653                                 $db->quote($this->question),
00654                                 $db->quote($this->getMaximumPoints() . ""),
00655                                 $db->quote($estw_time),
00656                                 $db->quote("$this->shuffle"),
00657                                 $db->quote($this->response),
00658                                 $db->quote("$complete"),
00659                                 $db->quote($created),
00660                                 $original_id
00661                         );
00662                         $result = $db->query($query);
00663                         
00664                         if ($result == DB_OK)
00665                         {
00666                                 $this->id = $this->ilias->db->getLastInsertId();
00667 
00668                                 // create page object of question
00669                                 $this->createPageObject();
00670 
00671                                 // Falls die Frage in einen Test eingefügt werden soll, auch diese Verbindung erstellen
00672                                 if ($this->getTestId() > 0)
00673                                 {
00674                                 $this->insertIntoTest($this->getTestId());
00675                                 }
00676                         }
00677                 }
00678                 else
00679                 {
00680                         // Vorhandenen Datensatz aktualisieren
00681                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, points = %s, working_time=%s, shuffle = %s, choice_response = %s, complete = %s WHERE question_id = %s",
00682                                 $db->quote($this->obj_id. ""),
00683                                 $db->quote($this->title),
00684                                 $db->quote($this->comment),
00685                                 $db->quote($this->author),
00686                                 $db->quote($this->question),
00687                                 $db->quote($this->getMaximumPoints() . ""),
00688                                 $db->quote($estw_time),
00689                                 $db->quote("$this->shuffle"),
00690                                 $db->quote($this->response),
00691                                 $db->quote("$complete"),
00692                                 $db->quote($this->id)
00693                         );
00694                         $result = $db->query($query);
00695                 }
00696                 if ($result == DB_OK)
00697                 {
00698                         // Antworten schreiben
00699                         // alte Antworten löschen
00700                         $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
00701                                 $db->quote($this->id)
00702                         );
00703                         $result = $db->query($query);
00704 
00705                         // Anworten wegschreiben
00706                         foreach ($this->answers as $key => $value)
00707                         {
00708                                 $answer_obj = $this->answers[$key];
00709                                 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, correctness, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
00710                                 $db->quote($this->id),
00711                                 $db->quote($answer_obj->get_answertext()),
00712                                 $db->quote($answer_obj->get_points() . ""),
00713                                 $db->quote($answer_obj->get_order() . ""),
00714                                 $db->quote($answer_obj->getState() . "")
00715                                 );
00716                                 $answer_result = $db->query($query);
00717                         }
00718                 }
00719                 parent::saveToDb($original_id);
00720         }
00721 
00731         function loadFromDb($question_id)
00732         {
00733                 global $ilias;
00734 
00735                 $db = & $ilias->db;
00736                 $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
00737                 $db->quote($question_id));
00738                 $result = $db->query($query);
00739                 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00740                 {
00741                         if ($result->numRows() == 1)
00742                         {
00743                                 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00744                                 $this->id = $question_id;
00745                                 $this->title = $data->title;
00746                                 $this->comment = $data->comment;
00747                                 $this->solution_hint = $data->solution_hint;
00748                                 $this->original_id = $data->original_id;
00749                                 $this->obj_id = $data->obj_fi;
00750                                 $this->author = $data->author;
00751                                 $this->owner = $data->owner;
00752                                 $this->points = $data->points;
00753                                 $this->question = $data->question_text;
00754                                 $this->response = $data->choice_response;
00755                                 $this->setShuffle($data->shuffle);
00756                                 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00757                         }
00758 
00759                         $query = sprintf("SELECT * FROM qpl_answers WHERE question_fi = %s ORDER BY aorder ASC",
00760                                 $db->quote($question_id));
00761 
00762                         $result = $db->query($query);
00763 
00764                         if (strcmp(strtolower(get_class($result)), db_result) == 0)
00765                         {
00766                                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00767                                 {
00768                                         if ($this->response == RESPONSE_SINGLE)
00769                                         {
00770                                                 if ($data->correctness == 0)
00771                                                 {
00772                                                         // fix for older single response answers where points could be given for unchecked answers
00773                                                         $data->correctness = 1;
00774                                                         $data->points = 0;
00775                                                 }
00776                                         }
00777                                         array_push($this->answers, new ASS_AnswerBinaryState($data->answertext, $data->points, $data->aorder, $data->correctness));
00778                                 }
00779                         }
00780                 }
00781                 parent::loadFromDb($question_id);
00782         }
00783 
00791         function addAnswer($answertext, $points, $answerorder, $correctness)
00792         {
00793                 array_push($this->answers, new ASS_AnswerBinaryState($answertext, $points, $answerorder, $correctness));
00794         }
00795         
00803         function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00804         {
00805                 if ($this->id <= 0)
00806                 {
00807                         // The question has not been saved. It cannot be duplicated
00808                         return;
00809                 }
00810                 // duplicate the question in database
00811                 $clone = $this;
00812                 include_once ("./assessment/classes/class.assQuestion.php");
00813                 $original_id = ASS_Question::_getOriginalId($this->id);
00814                 $clone->id = -1;
00815                 if ($title)
00816                 {
00817                         $clone->setTitle($title);
00818                 }
00819 
00820                 if ($author)
00821                 {
00822                         $clone->setAuthor($author);
00823                 }
00824                 if ($owner)
00825                 {
00826                         $clone->setOwner($owner);
00827                 }
00828 
00829                 if ($for_test)
00830                 {
00831                         $clone->saveToDb($original_id);
00832                 }
00833                 else
00834                 {
00835                         $clone->saveToDb();
00836                 }
00837 
00838                 // copy question page content
00839                 $clone->copyPageOfQuestion($original_id);
00840 
00841                 return $clone->id;
00842         }
00843 
00853         function get_question()
00854         {
00855                 return $this->question;
00856         }
00857 
00867         function set_question($question = "")
00868         {
00869                 $this->question = $question;
00870         }
00871 
00881         function get_response()
00882         {
00883                 return $this->response;
00884         }
00885 
00895         function set_response($response = "")
00896         {
00897                 $this->response = $response;
00898         }
00899 
00909         function get_output_type()
00910         {
00911                 return $this->output_type;
00912         }
00913 
00923         function set_output_type($output_type = OUTPUT_ORDER)
00924         {
00925                 $this->output_type = $output_type;
00926         }
00927 
00942         function add_answer(
00943                 $answertext = "",
00944                 $points = 0.0,
00945                 $state = 0,
00946                 $order = 0
00947         )
00948         {
00949                 $found = -1;
00950                 foreach ($this->answers as $key => $value)
00951                 {
00952                         if ($value->get_order() == $order)
00953                         {
00954                                 $found = $order;
00955                         }
00956                 }
00957                 if ($found >= 0)
00958                 {
00959                         // Antwort einfügen
00960                         $answer = new ASS_AnswerBinaryState($answertext, $points, $found, $state);
00961                         array_push($this->answers, $answer);
00962                         for ($i = $found + 1; $i < count($this->answers); $i++)
00963                         {
00964                                 $this->answers[$i] = $this->answers[$i-1];
00965                         }
00966                         $this->answers[$found] = $answer;
00967                 }
00968                 else
00969                 {
00970                         // Anwort anhängen
00971                         $answer = new ASS_AnswerBinaryState($answertext, $points, count($this->answers), $state);
00972                         array_push($this->answers, $answer);
00973                 }
00974         }
00975 
00985         function get_answer_count()
00986         {
00987                 return count($this->answers);
00988         }
00989 
01001         function get_answer($index = 0)
01002         {
01003                 if ($index < 0) return NULL;
01004                 if (count($this->answers) < 1) return NULL;
01005                 if ($index >= count($this->answers)) return NULL;
01006 
01007                 return $this->answers[$index];
01008         }
01009 
01020         function delete_answer($index = 0)
01021         {
01022                 if ($index < 0) return;
01023                 if (count($this->answers) < 1) return;
01024                 if ($index >= count($this->answers)) return;
01025                 unset($this->answers[$index]);
01026                 $this->answers = array_values($this->answers);
01027                 for ($i = 0; $i < count($this->answers); $i++)
01028                 {
01029                         if ($this->answers[$i]->get_order() > $index)
01030                         {
01031                                 $this->answers[$i]->set_order($i);
01032                         }
01033                 }
01034         }
01035 
01044         function flush_answers()
01045         {
01046                 $this->answers = array();
01047         }
01048 
01057         function getMaximumPoints()
01058         {
01059                 $points = array("set" => 0, "unset" => 0);
01060                 if ($this->get_response() == RESPONSE_SINGLE)
01061                 {
01062                         foreach ($this->answers as $key => $value) 
01063                         {
01064                                 if ($value->get_points() > $points["set"])
01065                                 {
01066                                         $points["set"] = $value->get_points();
01067                                 }
01068                         }
01069                         return $points["set"];
01070                 }
01071                 else
01072                 {
01073                         $allpoints = 0;
01074                         foreach ($this->answers as $key => $value) {
01075                                 $allpoints += $value->get_points();
01076                         }
01077                         return $allpoints;
01078                 }
01079         }
01080 
01092         function calculateReachedPoints($user_id, $test_id)
01093         {
01094                 global $ilDB;
01095                 
01096                 $found_values = array();
01097                 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01098                         $ilDB->quote($user_id),
01099                         $ilDB->quote($test_id),
01100                         $ilDB->quote($this->getId())
01101                 );
01102                 $result = $ilDB->query($query);
01103                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01104                 {
01105                         if (strcmp($data->value1, "") != 0)
01106                         {
01107                                 array_push($found_values, $data->value1);
01108                         }
01109                 }
01110                 $points = 0;
01111                 foreach ($this->answers as $key => $answer)
01112                 {
01113                         if ((count($found_values) > 0) || ($this->get_response() == RESPONSE_MULTIPLE))
01114                         {
01115                                 if ($answer->isStateChecked())
01116                                 {
01117                                         if (in_array($key, $found_values))
01118                                         {
01119                                                 $points += $answer->get_points();
01120                                         }
01121                                 }
01122                                 else
01123                                 {
01124                                         if (!in_array($key, $found_values))
01125                                         {
01126                                                 $points += $answer->get_points();
01127                                         }
01128                                 }
01129                         }
01130                 }
01131 
01132                 // check for special scoring options in test
01133                 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
01134                         $ilDB->quote($test_id)
01135                 );
01136                 $result = $ilDB->query($query);
01137                 if ($result->numRows() == 1)
01138                 {
01139                         $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
01140                         if ($row["mc_scoring"] == 0)
01141                         {
01142                                 if (!$this->wasAnsweredByUser($user_id, $test_id))
01143                                 {
01144                                         $points = 0;
01145                                 }
01146                         }
01147                         if ($row["count_system"] == 1)
01148                         {
01149                                 if ($points != $this->getMaximumPoints())
01150                                 {
01151                                         $points = 0;
01152                                 }
01153                         }
01154                 }
01155                 else
01156                 {
01157                         $points = 0;
01158                 }
01159                 return $points;
01160         }
01161         
01172         function wasAnsweredByUser($user_id, $test_id)
01173         {
01174                 global $ilDB;
01175                 $found_values = array();
01176                 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01177                         $ilDB->quote($user_id),
01178                         $ilDB->quote($test_id),
01179                         $ilDB->quote($this->getId())
01180                 );
01181                 $result = $ilDB->query($query);
01182                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01183                 {
01184                         if (strcmp($data->value1, "") != 0)
01185                         {
01186                                 array_push($found_values, $data->value1);
01187                         }
01188                 }
01189                 if (count($found_values) == 0)
01190                 {
01191                         return FALSE;
01192                 }
01193                 else
01194                 {
01195                         return TRUE;
01196                 }
01197         }
01198 
01208         function getReachedInformation($user_id, $test_id)
01209         {
01210                 $found_values = array();
01211                 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01212                 $this->ilias->db->quote($user_id),
01213                 $this->ilias->db->quote($test_id),
01214                 $this->ilias->db->quote($this->getId())
01215                 );
01216                 $result = $this->ilias->db->query($query);
01217                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01218                 {
01219                         array_push($found_values, $data->value1);
01220                 }
01221                 $counter = 1;
01222                 $user_result = array();
01223                 foreach ($found_values as $key => $value)
01224                 {
01225                         $solution = array(
01226                                 "order" => "$counter",
01227                                 "points" => 0,
01228                                 "true" => 0,
01229                                 "value" => "",
01230                                 );
01231                         if (strlen($value) > 0)
01232                         {
01233                                 $solution["value"] = $value;
01234                                 $solution["points"] = $this->answers[$value]->get_points();
01235                                 if ($this->answers[$value]->isStateChecked())
01236                                 {
01237                                         $solution["true"] = 1;
01238                                 }
01239                         }
01240                         $counter++;
01241                         $user_result[$value] = $solution;
01242                 }
01243                 return $user_result;
01244         }
01245 
01256         function saveWorkingData($test_id, $limit_to = LIMIT_NO_LIMIT)
01257         {
01258                 global $ilDB;
01259                 global $ilUser;
01260 
01261                 $db =& $ilDB->db;
01262 
01263                 if ($this->response == RESPONSE_SINGLE)
01264                 {
01265                         $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01266                                 $db->quote($ilUser->id),
01267                                 $db->quote($test_id),
01268                                 $db->quote($this->getId())
01269                         );
01270                         $result = $db->query($query);
01271                         $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
01272                         $update = $row->solution_id;
01273                         if ($update)
01274                         {
01275                                 $query = sprintf("UPDATE tst_solutions SET value1 = %s WHERE solution_id = %s",
01276                                         $db->quote($_POST["multiple_choice_result"]),
01277                                         $db->quote($update));
01278                         }
01279                         else
01280                         {
01281                                 $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, NULL, NULL)",
01282                                         $db->quote($ilUser->id),
01283                                         $db->quote($test_id),
01284                                         $db->quote($this->getId()),
01285                                         $db->quote($_POST["multiple_choice_result"])
01286                                 );
01287                         }
01288                         $result = $db->query($query);
01289                 }
01290                 else
01291                 {
01292                         $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01293                                 $db->quote($ilUser->id),
01294                                 $db->quote($test_id),
01295                                 $db->quote($this->getId())
01296                         );
01297                         $result = $db->query($query);
01298                         foreach ($_POST as $key => $value)
01299                         {
01300                                 if (preg_match("/^multiple_choice_result_(\d+)/", $key, $matches))
01301                                 {
01302                                         $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, NULL, NULL)",
01303                                                 $db->quote($ilUser->id),
01304                                                 $db->quote($test_id),
01305                                                 $db->quote($this->getId()),
01306                                                 $db->quote($value)
01307                                         );
01308                                         $result = $db->query($query);
01309                                 }
01310                         }
01311                 }
01312     parent::saveWorkingData($test_id);
01313                 return true;
01314         }
01315 
01316         function syncWithOriginal()
01317         {
01318                 global $ilias;
01319                 if ($this->original_id)
01320                 {
01321                         $complete = 0;
01322                         if ($this->isComplete())
01323                         {
01324                                 $complete = 1;
01325                         }
01326                         $db = & $ilias->db;
01327         
01328                         $estw_time = $this->getEstimatedWorkingTime();
01329                         $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01330         
01331                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, points = %s, working_time=%s, shuffle = %s, choice_response = %s, complete = %s WHERE question_id = %s",
01332                                 $db->quote($this->obj_id. ""),
01333                                 $db->quote($this->title. ""),
01334                                 $db->quote($this->comment. ""),
01335                                 $db->quote($this->author. ""),
01336                                 $db->quote($this->question. ""),
01337                                 $db->quote($this->getMaximumPoints() . ""),
01338                                 $db->quote($estw_time. ""),
01339                                 $db->quote($this->shuffle. ""),
01340                                 $db->quote($this->response. ""),
01341                                 $db->quote($complete. ""),
01342                                 $db->quote($this->original_id. "")
01343                         );
01344                         $result = $db->query($query);
01345 
01346                         if ($result == DB_OK)
01347                         {
01348                                 // write answers
01349                                 // delete old answers
01350                                 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
01351                                         $db->quote($this->original_id)
01352                                 );
01353                                 $result = $db->query($query);
01354         
01355                                 foreach ($this->answers as $key => $value)
01356                                 {
01357                                         $answer_obj = $this->answers[$key];
01358                                         $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, correctness, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
01359                                         $db->quote($this->original_id. ""),
01360                                         $db->quote($answer_obj->get_answertext(). ""),
01361                                         $db->quote($answer_obj->get_points() . ""),
01362                                         $db->quote($answer_obj->get_order() . ""),
01363                                         $db->quote($answer_obj->getState() . "")
01364                                         );
01365                                         $answer_result = $db->query($query);
01366                                 }
01367                         }
01368                         parent::syncWithOriginal();
01369                 }
01370         }
01371 
01372         function createRandomSolution($test_id, $user_id)
01373         {
01374                 mt_srand((double)microtime()*1000000);
01375                 $answer = mt_rand(0, count($this->answers)-1);
01376 
01377                 global $ilDB;
01378                 global $ilUser;
01379 
01380                 $db =& $ilDB->db;
01381 
01382                 if ($this->response == RESPONSE_SINGLE)
01383                 {
01384                         $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01385                                 $db->quote($user_id),
01386                                 $db->quote($test_id),
01387                                 $db->quote($this->getId())
01388                         );
01389                         $result = $db->query($query);
01390                         $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
01391                         $update = $row->solution_id;
01392                         if ($update)
01393                         {
01394                                 $query = sprintf("UPDATE tst_solutions SET value1 = %s WHERE solution_id = %s",
01395                                         $db->quote($answer),
01396                                         $db->quote($update));
01397                         }
01398                         else
01399                         {
01400                                 $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, NULL, NULL)",
01401                                         $db->quote($user_id),
01402                                         $db->quote($test_id),
01403                                         $db->quote($this->getId()),
01404                                         $db->quote($answer)
01405                                 );
01406                         }
01407                         $result = $db->query($query);
01408                 }
01409                 else
01410                 {
01411                         $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01412                                 $db->quote($user_id),
01413                                 $db->quote($test_id),
01414                                 $db->quote($this->getId())
01415                         );
01416                         $result = $db->query($query);
01417                         $answerarray = array();
01418                         for ($i = 0; $i < $answer; $i++)
01419                         {
01420                                 $manswer = mt_rand(0, count($this->answers)-1);
01421                                 $answerarray[$manswer]++;
01422                         }
01423                         foreach ($answerarray as $key => $value)
01424                         {
01425                                 $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, NULL, NULL)",
01426                                         $db->quote($user_id),
01427                                         $db->quote($test_id),
01428                                         $db->quote($this->getId()),
01429                                         $db->quote($key)
01430                                 );
01431                                 $result = $db->query($query);
01432                         }
01433                 }
01434         }
01435         
01444         function getQuestionType()
01445         {
01446                 if ($this->response == RESPONSE_SINGLE)
01447                 {
01448                         $question_type = 1;
01449                 }
01450                 else
01451                 {
01452                         $question_type = 2;
01453                 }
01454                 return $question_type;
01455         }
01456         
01457 }
01458 
01459 ?>

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