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

assessment/classes/class.assMatchingQuestion.php

Go to the documentation of this file.
00001 <?php
00002 /*
00003    +----------------------------------------------------------------------------+
00004    | ILIAS open source                                                          |
00005    +----------------------------------------------------------------------------+
00006    | Copyright (c) 1998-2001 ILIAS open source, University of Cologne           |
00007    |                                                                            |
00008    | This program is free software; you can redistribute it and/or              |
00009    | modify it under the terms of the GNU General Public License                |
00010    | as published by the Free Software Foundation; either version 2             |
00011    | of the License, or (at your option) any later version.                     |
00012    |                                                                            |
00013    | This program is distributed in the hope that it will be useful,            |
00014    | but WITHOUT ANY WARRANTY; without even the implied warranty of             |
00015    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              |
00016    | GNU General Public License for more details.                               |
00017    |                                                                            |
00018    | You should have received a copy of the GNU General Public License          |
00019    | along with this program; if not, write to the Free Software                |
00020    | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
00021    +----------------------------------------------------------------------------+
00022 */
00023 
00024 include_once "./assessment/classes/class.assQuestion.php";
00025 include_once "./assessment/classes/inc.AssessmentConstants.php";
00026 
00037 class ASS_MatchingQuestion extends ASS_Question
00038 {
00046         var $question;
00047 
00055         var $matchingpairs;
00056 
00065         var $matching_type;
00066 
00079         function ASS_MatchingQuestion (
00080                 $title = "",
00081                 $comment = "",
00082                 $author = "",
00083                 $owner = -1,
00084                 $question = "",
00085                 $matching_type = MT_TERMS_DEFINITIONS
00086         )
00087         {
00088                 $this->ASS_Question($title, $comment, $author, $owner);
00089                 $this->matchingpairs = array();
00090                 $this->question = $question;
00091                 $this->matching_type = $matching_type;
00092         }
00093 
00102         function isComplete()
00103         {
00104                 if (($this->title) and ($this->author) and ($this->question) and (count($this->matchingpairs)) and ($this->getMaximumPoints() > 0))
00105                 {
00106                         return true;
00107                 }
00108                 else
00109                 {
00110                         return false;
00111                 }
00112         }
00113 
00123         function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
00124         {
00125                 include_once("./classes/class.ilXmlWriter.php");
00126                 $a_xml_writer = new ilXmlWriter;
00127                 // set xml header
00128                 $a_xml_writer->xmlHeader();
00129                 $a_xml_writer->xmlStartTag("questestinterop");
00130                 $attrs = array(
00131                         "ident" => "il_".IL_INST_ID."_qst_".$this->getId(),
00132                         "title" => $this->getTitle()
00133                 );
00134                 $a_xml_writer->xmlStartTag("item", $attrs);
00135                 // add question description
00136                 $a_xml_writer->xmlElement("qticomment", NULL, $this->getComment());
00137                 // add estimated working time
00138                 $workingtime = $this->getEstimatedWorkingTime();
00139                 $duration = sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]);
00140                 $a_xml_writer->xmlElement("duration", NULL, $duration);
00141                 // add ILIAS specific metadata
00142                 $a_xml_writer->xmlStartTag("itemmetadata");
00143                 $a_xml_writer->xmlStartTag("qtimetadata");
00144                 $a_xml_writer->xmlStartTag("qtimetadatafield");
00145                 $a_xml_writer->xmlElement("fieldlabel", NULL, "ILIAS_VERSION");
00146                 $a_xml_writer->xmlElement("fieldentry", NULL, $this->ilias->getSetting("ilias_version"));
00147                 $a_xml_writer->xmlEndTag("qtimetadatafield");
00148                 $a_xml_writer->xmlStartTag("qtimetadatafield");
00149                 $a_xml_writer->xmlElement("fieldlabel", NULL, "QUESTIONTYPE");
00150                 $a_xml_writer->xmlElement("fieldentry", NULL, MATCHING_QUESTION_IDENTIFIER);
00151                 $a_xml_writer->xmlEndTag("qtimetadatafield");
00152                 $a_xml_writer->xmlStartTag("qtimetadatafield");
00153                 $a_xml_writer->xmlElement("fieldlabel", NULL, "AUTHOR");
00154                 $a_xml_writer->xmlElement("fieldentry", NULL, $this->getAuthor());
00155                 $a_xml_writer->xmlEndTag("qtimetadatafield");
00156                 $a_xml_writer->xmlEndTag("qtimetadata");
00157                 $a_xml_writer->xmlEndTag("itemmetadata");
00158 
00159                 // PART I: qti presentation
00160                 $attrs = array(
00161                         "label" => $this->getTitle()
00162                 );
00163                 $a_xml_writer->xmlStartTag("presentation", $attrs);
00164                 // add flow to presentation
00165                 $a_xml_writer->xmlStartTag("flow");
00166                 // add material with question text to presentation
00167                 $a_xml_writer->xmlStartTag("material");
00168                 $a_xml_writer->xmlElement("mattext", NULL, $this->get_question());
00169                 $a_xml_writer->xmlEndTag("material");
00170                 // add answers to presentation
00171                 $attrs = array();
00172                 if ($this->get_matching_type() == MT_TERMS_PICTURES)
00173                 {
00174                         $attrs = array(
00175                                 "ident" => "MQP",
00176                                 "rcardinality" => "Multiple"
00177                         );
00178                 }
00179                 else
00180                 {
00181                         $attrs = array(
00182                                 "ident" => "MQT",
00183                                 "rcardinality" => "Multiple"
00184                         );
00185                 }
00186                 if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
00187                 {
00188                         $attrs["output"] = "javascript";
00189                 }
00190                 $a_xml_writer->xmlStartTag("response_grp", $attrs);
00191                 $solution = $this->getSuggestedSolution(0);
00192                 if (count($solution))
00193                 {
00194                         if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00195                         {
00196                                 $a_xml_writer->xmlStartTag("material");
00197                                 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00198                                 if (strcmp($matches[1], "") != 0)
00199                                 {
00200                                         $intlink = $solution["internal_link"];
00201                                 }
00202                                 $attrs = array(
00203                                         "label" => "suggested_solution"
00204                                 );
00205                                 $a_xml_writer->xmlElement("mattext", $attrs, $intlink);
00206                                 $a_xml_writer->xmlEndTag("material");
00207                         }
00208                 }
00209                 // shuffle output
00210                 $attrs = array();
00211                 if ($this->getShuffle())
00212                 {
00213                         $attrs = array(
00214                                 "shuffle" => "Yes"
00215                         );
00216                 }
00217                 else
00218                 {
00219                         $attrs = array(
00220                                 "shuffle" => "No"
00221                         );
00222                 }
00223                 $a_xml_writer->xmlStartTag("render_choice", $attrs);
00224                 // add answertext
00225                 $matchingtext_orders = array();
00226                 foreach ($this->matchingpairs as $index => $matchingpair)
00227                 {
00228                         array_push($matchingtext_orders, $matchingpair->getTermId());
00229                 }
00230 
00231                 // shuffle it
00232                 $pkeys = array_keys($this->matchingpairs);
00233                 if ($this->getshuffle() && $a_shuffle)
00234                 {
00235                         $pkeys = $this->pcArrayShuffle($pkeys);
00236                 }
00237                 // add answers
00238                 foreach ($pkeys as $index)
00239                 {
00240                         $matchingpair = $this->matchingpairs[$index];
00241                         $attrs = array(
00242                                 "ident" => $matchingpair->getDefinitionId(),
00243                                 "match_max" => "1",
00244                                 "match_group" => join($matchingtext_orders, ",")
00245                         );
00246                         $a_xml_writer->xmlStartTag("response_label", $attrs);
00247                         $a_xml_writer->xmlStartTag("material");
00248                         if ($this->get_matching_type() == MT_TERMS_PICTURES)
00249                         {
00250                                 if ($force_image_references)
00251                                 {
00252                                         $attrs = array(
00253                                                 "imagtype" => "image/jpeg",
00254                                                 "label" => $matchingpair->getPicture(),
00255                                                 "uri" => $this->getImagePathWeb() . $matchingpair->getPicture()
00256                                         );
00257                                         $a_xml_writer->xmlElement("matimage", $attrs);
00258                                 }
00259                                 else
00260                                 {
00261                                         $imagepath = $this->getImagePath() . $matchingpair->getPicture();
00262                                         $fh = @fopen($imagepath, "rb");
00263                                         if ($fh != false)
00264                                         {
00265                                                 $imagefile = fread($fh, filesize($imagepath));
00266                                                 fclose($fh);
00267                                                 $base64 = base64_encode($imagefile);
00268                                                 $attrs = array(
00269                                                         "imagtype" => "image/jpeg",
00270                                                         "label" => $matchingpair->getPicture(),
00271                                                         "embedded" => "base64"
00272                                                 );
00273                                                 $a_xml_writer->xmlElement("matimage", $attrs, $base64, FALSE, FALSE);
00274                                         }
00275                                 }
00276                         }
00277                         else
00278                         {
00279                                 $a_xml_writer->xmlElement("mattext", NULL, $matchingpair->getDefinition());
00280                         }
00281                         $a_xml_writer->xmlEndTag("material");
00282                         $a_xml_writer->xmlEndTag("response_label");
00283                 }
00284                 // shuffle again to get another order for the terms or pictures
00285                 if ($this->getshuffle() && $a_shuffle)
00286                 {
00287                         $pkeys = $this->pcArrayShuffle($pkeys);
00288                 }
00289                 // add matchingtext
00290                 foreach ($pkeys as $index)
00291                 {
00292                         $matchingpair = $this->matchingpairs[$index];
00293                         $attrs = array(
00294                                 "ident" => $matchingpair->getTermId()
00295                         );
00296                         $a_xml_writer->xmlStartTag("response_label", $attrs);
00297                         $a_xml_writer->xmlStartTag("material");
00298                         $a_xml_writer->xmlElement("mattext", NULL, $matchingpair->getTerm());
00299                         $a_xml_writer->xmlEndTag("material");
00300                         $a_xml_writer->xmlEndTag("response_label");
00301                 }
00302                 $a_xml_writer->xmlEndTag("render_choice");
00303                 $a_xml_writer->xmlEndTag("response_grp");
00304                 $a_xml_writer->xmlEndTag("flow");
00305                 $a_xml_writer->xmlEndTag("presentation");
00306 
00307                 // PART II: qti resprocessing
00308                 $a_xml_writer->xmlStartTag("resprocessing");
00309                 $a_xml_writer->xmlStartTag("outcomes");
00310                 $a_xml_writer->xmlStartTag("decvar");
00311                 $a_xml_writer->xmlEndTag("decvar");
00312                 $a_xml_writer->xmlEndTag("outcomes");
00313                 // add response conditions
00314                 foreach ($this->matchingpairs as $index => $matchingpair)
00315                 {
00316                         $attrs = array(
00317                                 "continue" => "Yes"
00318                         );
00319                         $a_xml_writer->xmlStartTag("respcondition", $attrs);
00320                         // qti conditionvar
00321                         $a_xml_writer->xmlStartTag("conditionvar");
00322                         $attrs = array();
00323                         if ($this->get_matching_type() == MT_TERMS_PICTURES)
00324                         {
00325                                 $attrs = array(
00326                                         "respident" => "MQP"
00327                                 );
00328                         }
00329                                 else
00330                         {
00331                                 $attrs = array(
00332                                         "respident" => "MQT"
00333                                 );
00334                         }
00335                         $a_xml_writer->xmlElement("varsubset", $attrs, $matchingpair->getTermId() . "," . $matchingpair->getDefinitionId());
00336                         $a_xml_writer->xmlEndTag("conditionvar");
00337 
00338                         // qti setvar
00339                         $attrs = array(
00340                                 "action" => "Add"
00341                         );
00342                         $a_xml_writer->xmlElement("setvar", $attrs, $matchingpair->getPoints());
00343                         // qti displayfeedback
00344                         $attrs = array(
00345                                 "feedbacktype" => "Response",
00346                                 "linkrefid" => "correct_" . $matchingpair->getTermId() . "_" . $matchingpair->getDefinitionId()
00347                         );
00348                         $a_xml_writer->xmlElement("displayfeedback", $attrs);
00349                         $a_xml_writer->xmlEndTag("respcondition");
00350                 }
00351                 $a_xml_writer->xmlEndTag("resprocessing");
00352 
00353                 // PART III: qti itemfeedback
00354                 foreach ($this->matchingpairs as $index => $matchingpair)
00355                 {
00356                         $attrs = array(
00357                                 "ident" => "correct_" . $matchingpair->getTermId() . "_" . $matchingpair->getDefinitionId(),
00358                                 "view" => "All"
00359                         );
00360                         $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
00361                         // qti flow_mat
00362                         $a_xml_writer->xmlStartTag("flow_mat");
00363                         $a_xml_writer->xmlStartTag("material");
00364                         $a_xml_writer->xmlElement("mattext");
00365                         $a_xml_writer->xmlEndTag("material");
00366                         $a_xml_writer->xmlEndTag("flow_mat");
00367                         $a_xml_writer->xmlEndTag("itemfeedback");
00368                 }
00369                 $a_xml_writer->xmlEndTag("item");
00370                 $a_xml_writer->xmlEndTag("questestinterop");
00371 
00372                 $xml = $a_xml_writer->xmlDumpMem(FALSE);
00373                 if (!$a_include_header)
00374                 {
00375                         $pos = strpos($xml, "?>");
00376                         $xml = substr($xml, $pos + 2);
00377                 }
00378                 return $xml;
00379         }
00380 
00389         function saveToDb($original_id = "")
00390         {
00391                 global $ilias;
00392 
00393                 $db =& $ilias->db;
00394                 $complete = 0;
00395                 if ($this->isComplete())
00396                 {
00397                         $complete = 1;
00398                 }
00399                 $estw_time = $this->getEstimatedWorkingTime();
00400                 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00401 
00402                 if ($original_id)
00403                 {
00404                         $original_id = $db->quote($original_id);
00405                 }
00406                 else
00407                 {
00408                         $original_id = "NULL";
00409                 }
00410 
00411                 if ($this->id == -1)
00412                 {
00413                         // Neuen Datensatz schreiben
00414                         $now = getdate();
00415                         $question_type = $this->getQuestionType();
00416                         $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00417                         $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, working_time, shuffle, matching_type, points, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00418                                 $db->quote($question_type. ""),
00419                                 $db->quote($this->obj_id. ""),
00420                                 $db->quote($this->title. ""),
00421                                 $db->quote($this->comment. ""),
00422                                 $db->quote($this->author. ""),
00423                                 $db->quote($this->owner. ""),
00424                                 $db->quote($this->question. ""),
00425                                 $db->quote($estw_time. ""),
00426                                 $db->quote($this->shuffle . ""),
00427                                 $db->quote($this->matching_type. ""),
00428                                 $db->quote($this->getMaximumPoints() . ""),
00429                                 $db->quote($complete. ""),
00430                                 $db->quote($created. ""),
00431                                 $original_id
00432                         );
00433 
00434                         $result = $db->query($query);
00435                         if ($result == DB_OK)
00436                         {
00437                                 $this->id = $this->ilias->db->getLastInsertId();
00438 
00439                                 // create page object of question
00440                                 $this->createPageObject();
00441 
00442                                 // Falls die Frage in einen Test eingefügt werden soll, auch diese Verbindung erstellen
00443                                 if ($this->getTestId() > 0)
00444                                 {
00445                                         $this->insertIntoTest($this->getTestId());
00446                                 }
00447                         }
00448                 }
00449                 else
00450                 {
00451                         // Vorhandenen Datensatz aktualisieren
00452                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time=%s, shuffle = %s, matching_type = %s, points = %s, complete = %s WHERE question_id = %s",
00453                                 $db->quote($this->obj_id. ""),
00454                                 $db->quote($this->title. ""),
00455                                 $db->quote($this->comment. ""),
00456                                 $db->quote($this->author. ""),
00457                                 $db->quote($this->question. ""),
00458                                 $db->quote($estw_time. ""),
00459                                 $db->quote($this->shuffle . ""),
00460                                 $db->quote($this->matching_type. ""),
00461                                 $db->quote($this->getMaximumPoints() . ""),
00462                                 $db->quote($complete. ""),
00463                                 $db->quote($this->id. "")
00464                         );
00465                         $result = $db->query($query);
00466                 }
00467 
00468                 if ($result == DB_OK)
00469                 {
00470                         // Antworten schreiben
00471                         // alte Antworten löschen
00472                         $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
00473                                 $db->quote($this->id)
00474                         );
00475                         $result = $db->query($query);
00476 
00477                         // Anworten wegschreiben
00478                         foreach ($this->matchingpairs as $key => $value)
00479                         {
00480                                 $matching_obj = $this->matchingpairs[$key];
00481                                 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, matchingtext, matching_order, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
00482                                         $db->quote($this->id),
00483                                         $db->quote($matching_obj->getTerm() . ""),
00484                                         $db->quote($matching_obj->getPoints() . ""),
00485                                         $db->quote($matching_obj->getTermId() . ""),
00486                                         $db->quote($matching_obj->getDefinition() . ""),
00487                                         $db->quote($matching_obj->getDefinitionId() . "")
00488                                 );
00489                                 $matching_result = $db->query($query);
00490                         }
00491                 }
00492                 parent::saveToDb($original_id);
00493         }
00494 
00504         function loadFromDb($question_id)
00505         {
00506                 global $ilias;
00507                 $db =& $ilias->db;
00508 
00509                 $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
00510                         $db->quote($question_id)
00511                 );
00512                 $result = $db->query($query);
00513                 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00514                 {
00515                         if ($result->numRows() == 1)
00516                         {
00517                                 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00518                                 $this->id = $question_id;
00519                                 $this->title = $data->title;
00520                                 $this->comment = $data->comment;
00521                                 $this->author = $data->author;
00522                                 $this->solution_hint = $data->solution_hint;
00523                                 $this->obj_id = $data->obj_fi;
00524                                 $this->original_id = $data->original_id;
00525                                 $this->owner = $data->owner;
00526                                 $this->matching_type = $data->matching_type;
00527                                 $this->question = $data->question_text;
00528                                 $this->points = $data->points;
00529                                 $this->shuffle = $data->shuffle;
00530                                 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00531                         }
00532 
00533                         $query = sprintf("SELECT * FROM qpl_answers WHERE question_fi = %s ORDER BY answer_id ASC",
00534                                 $db->quote($question_id)
00535                         );
00536                         $result = $db->query($query);
00537                         include_once "./assessment/classes/class.assAnswerMatching.php";
00538                         if (strcmp(strtolower(get_class($result)), db_result) == 0)
00539                         {
00540                                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00541                                 {
00542                                         array_push($this->matchingpairs, new ASS_AnswerMatching($data->answertext, $data->points, $data->aorder, $data->matchingtext, $data->matching_order));
00543                                 }
00544                         }
00545                 }
00546                 parent::loadFromDb($question_id);
00547         }
00548 
00556         function addMatchingPair($answertext, $points, $answerorder, $matchingtext, $matchingorder)
00557         {
00558                 include_once "./assessment/classes/class.assAnswerMatching.php";
00559                 array_push($this->matchingpairs, new ASS_AnswerMatching($answertext, $points, $answerorder, $matchingtext, $matchingorder));
00560         }
00561         
00562         
00570         function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00571         {
00572                 if ($this->id <= 0)
00573                 {
00574                         // The question has not been saved. It cannot be duplicated
00575                         return;
00576                 }
00577                 // duplicate the question in database
00578                 $this_id = $this->getId();
00579                 $clone = $this;
00580                 include_once ("./assessment/classes/class.assQuestion.php");
00581                 $original_id = ASS_Question::_getOriginalId($this->id);
00582                 $clone->id = -1;
00583                 if ($title)
00584                 {
00585                         $clone->setTitle($title);
00586                 }
00587                 if ($author)
00588                 {
00589                         $clone->setAuthor($author);
00590                 }
00591                 if ($owner)
00592                 {
00593                         $clone->setOwner($owner);
00594                 }
00595                 if ($for_test)
00596                 {
00597                         $clone->saveToDb($original_id);
00598                 }
00599                 else
00600                 {
00601                         $clone->saveToDb();
00602                 }
00603 
00604                 // copy question page content
00605                 $clone->copyPageOfQuestion($this_id);
00606 
00607                 // duplicate the image
00608                 $clone->duplicateImages($this_id);
00609                 return $clone->id;
00610         }
00611 
00619         function copyObject($target_questionpool, $title = "")
00620         {
00621                 if ($this->id <= 0)
00622                 {
00623                         // The question has not been saved. It cannot be duplicated
00624                         return;
00625                 }
00626                 // duplicate the question in database
00627                 $clone = $this;
00628                 include_once ("./assessment/classes/class.assQuestion.php");
00629                 $original_id = ASS_Question::_getOriginalId($this->id);
00630                 $clone->id = -1;
00631                 if ($title)
00632                 {
00633                         $clone->setTitle($title);
00634                 }
00635                 $source_questionpool = $this->getObjId();
00636                 $clone->setObjId($target_questionpool);
00637                 $clone->saveToDb();
00638 
00639                 // copy question page content
00640                 $clone->copyPageOfQuestion($original_id);
00641 
00642                 // duplicate the image
00643                 $clone->copyImages($original_id, $source_questionpool);
00644                 return $clone->id;
00645         }
00646 
00647         function duplicateImages($question_id)
00648         {
00649                 if ($this->get_matching_type() == MT_TERMS_PICTURES)
00650                 {
00651                         $imagepath = $this->getImagePath();
00652                         $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00653                         if (!file_exists($imagepath))
00654                         {
00655                                 ilUtil::makeDirParents($imagepath);
00656                         }
00657                         foreach ($this->matchingpairs as $answer)
00658                         {
00659                                 $filename = $answer->getPicture();
00660                                 if (!copy($imagepath_original . $filename, $imagepath . $filename))
00661                                 {
00662                                         print "image could not be duplicated!!!! ";
00663                                 }
00664                                 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg"))
00665                                 {
00666                                         print "image thumbnail could not be duplicated!!!! ";
00667                                 }
00668                         }
00669                 }
00670         }
00671 
00672         function copyImages($question_id, $source_questionpool)
00673         {
00674                 if ($this->get_matching_type() == MT_TERMS_PICTURES)
00675                 {
00676                         $imagepath = $this->getImagePath();
00677                         $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00678                         $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
00679                         if (!file_exists($imagepath))
00680                         {
00681                                 ilUtil::makeDirParents($imagepath);
00682                         }
00683                         foreach ($this->matchingpairs as $answer)
00684                         {
00685                                 $filename = $answer->getPicture();
00686                                 if (!copy($imagepath_original . $filename, $imagepath . $filename))
00687                                 {
00688                                         print "image could not be duplicated!!!! ";
00689                                 }
00690                                 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg"))
00691                                 {
00692                                         print "image thumbnail could not be duplicated!!!! ";
00693                                 }
00694                         }
00695                 }
00696         }
00697 
00707         function set_question($question = "")
00708         {
00709                 $this->question = $question;
00710         }
00711 
00721         function set_matching_type($matching_type = MT_TERMS_DEFINITIONS)
00722         {
00723                 $this->matching_type = $matching_type;
00724         }
00725 
00735         function get_question()
00736         {
00737                 return $this->question;
00738         }
00739 
00749         function get_matching_type()
00750         {
00751                 return $this->matching_type;
00752         }
00753 
00768         function add_matchingpair(
00769                 $term = "",
00770                 $picture_or_definition = "",
00771                 $points = 0.0,
00772                 $term_id = 0,
00773                 $picture_or_definition_id = 0
00774         )
00775         {
00776                 // append answer
00777                 if ($term_id == 0)
00778                 {
00779                         $term_id = $this->get_random_id();
00780                 }
00781 
00782                 if ($picture_or_definition_id == 0)
00783                 {
00784                         $picture_or_definition_id = $this->get_random_id();
00785                 }
00786                 include_once "./assessment/classes/class.assAnswerMatching.php";
00787                 $matchingpair = new ASS_AnswerMatching($term, $points, $term_id, $picture_or_definition, $picture_or_definition_id);
00788                 array_push($this->matchingpairs, $matchingpair);
00789         }
00790 
00802         function get_matchingpair($index = 0)
00803         {
00804                 if ($index < 0)
00805                 {
00806                         return NULL;
00807                 }
00808                 if (count($this->matchingpairs) < 1)
00809                 {
00810                         return NULL;
00811                 }
00812                 if ($index >= count($this->matchingpairs))
00813                 {
00814                         return NULL;
00815                 }
00816                 return $this->matchingpairs[$index];
00817         }
00818 
00829         function delete_matchingpair($index = 0)
00830         {
00831                 if ($index < 0)
00832                 {
00833                         return;
00834                 }
00835                 if (count($this->matchingpairs) < 1)
00836                 {
00837                         return;
00838                 }
00839                 if ($index >= count($this->matchingpairs))
00840                 {
00841                         return;
00842                 }
00843                 unset($this->matchingpairs[$index]);
00844                 $this->matchingpairs = array_values($this->matchingpairs);
00845         }
00846 
00855         function flush_matchingpairs()
00856         {
00857                 $this->matchingpairs = array();
00858         }
00859 
00869         function get_matchingpair_count()
00870         {
00871                 return count($this->matchingpairs);
00872         }
00873 
00885         function calculateReachedPoints($user_id, $test_id, $pass = NULL)
00886         {
00887                 global $ilDB;
00888                 
00889                 $found_value1 = array();
00890                 $found_value2 = array();
00891                 if (is_null($pass))
00892                 {
00893                         $pass = $this->getSolutionMaxPass($user_id, $test_id);
00894                 }
00895                 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
00896                         $ilDB->quote($user_id . ""),
00897                         $ilDB->quote($test_id . ""),
00898                         $ilDB->quote($this->getId() . ""),
00899                         $ilDB->quote($pass . "")
00900                 );
00901                 $result = $ilDB->query($query);
00902                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00903                 {
00904                         if (strcmp($data->value1, "") != 0)
00905                         {
00906                                 array_push($found_value1, $data->value1);
00907                                 array_push($found_value2, $data->value2);
00908                         }
00909                 }
00910                 $points = 0;
00911                 foreach ($found_value2 as $key => $value)
00912                 {
00913                         foreach ($this->matchingpairs as $answer_key => $answer_value)
00914                         {
00915                                 if (($answer_value->getDefinitionId() == $value) and ($answer_value->getTermId() == $found_value1[$key]))
00916                                 {
00917                                         $points += $answer_value->getPoints();
00918                                 }
00919                         }
00920                 }
00921 
00922                 // check for special scoring options in test
00923                 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
00924                         $ilDB->quote($test_id)
00925                 );
00926                 $result = $ilDB->query($query);
00927                 if ($result->numRows() == 1)
00928                 {
00929                         $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00930                         if ($row["count_system"] == 1)
00931                         {
00932                                 if ($points != $this->getMaximumPoints())
00933                                 {
00934                                         $points = 0;
00935                                 }
00936                         }
00937                 }
00938                 else
00939                 {
00940                         $points = 0;
00941                 }
00942                 return $points;
00943         }
00944 
00954         function getReachedInformation($user_id, $test_id, $pass = NULL)
00955         {
00956                 $found_value1 = array();
00957                 $found_value2 = array();
00958                 if (is_null($pass))
00959                 {
00960                         $pass = $this->getSolutionMaxPass($user_id, $test_id);
00961                 }
00962                 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
00963                         $this->ilias->db->quote($user_id . ""),
00964                         $this->ilias->db->quote($test_id . ""),
00965                         $this->ilias->db->quote($this->getId() . ""),
00966                         $this->ilias->db->quote($pass . "")
00967                 );
00968                 $result = $this->ilias->db->query($query);
00969                 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00970                 {
00971                         array_push($found_value1, $data->value1);
00972                         array_push($found_value2, $data->value2);
00973                 }
00974                 $counter = 1;
00975                 $user_result = array();
00976                 foreach ($found_value1 as $key => $value)
00977                 {
00978                         $solution = array(
00979                                 "order" => "$counter",
00980                                 "points" => 0,
00981                                 "true" => 0,
00982                                 "term" => "",
00983                                 "definition" => ""
00984                         );
00985                         foreach ($this->matchingpairs as $answer_key => $answer_value)
00986                         {
00987                                 if (($answer_value->getDefinitionId() == $found_value2[$key]) and ($answer_value->getTermId() == $value))
00988                                 {
00989                                         $points += $answer_value->getPoints();
00990                                         $solution["points"] = $answer_value->getPoints();
00991                                         $solution["term"] = $value;
00992                                         $solution["definition"] = $found_value2[$key];
00993                                         $solution["true"] = 1;
00994                                 }
00995                                 else
00996                                 {
00997                                         $solution["term"] = $value;
00998                                         $solution["definition"] = $found_value2[$key];
00999                                 }
01000                         }
01001                         $counter++;
01002                         array_push($user_result, $solution);
01003                 }
01004                 return $user_result;
01005         }
01006 
01015         function getMaximumPoints()
01016         {
01017                 $points = 0;
01018                 foreach ($this->matchingpairs as $key => $value)
01019                 {
01020                         if ($value->getPoints() > 0)
01021                         {
01022                                 $points += $value->getPoints();
01023                         }
01024                 }
01025                 return $points;
01026         }
01027 
01038         function set_image_file($image_filename, $image_tempfilename = "")
01039         {
01040                 $result = 0;
01041                 if (!empty($image_tempfilename))
01042                 {
01043                         $image_filename = str_replace(" ", "_", $image_filename);
01044                         $imagepath = $this->getImagePath();
01045                         if (!file_exists($imagepath))
01046                         {
01047                                 ilUtil::makeDirParents($imagepath);
01048                         }
01049                         //if (!move_uploaded_file($image_tempfilename, $imagepath . $image_filename))
01050                         if (!ilUtil::moveUploadedFile($image_tempfilename, $image_filename, $imagepath.$image_filename))
01051                         {
01052                                 $result = 2;
01053                         }
01054                         else
01055                         {
01056                                 include_once "./content/classes/Media/class.ilObjMediaObject.php";
01057                                 $mimetype = ilObjMediaObject::getMimeType($imagepath . $image_filename);
01058                                 if (!preg_match("/^image/", $mimetype))
01059                                 {
01060                                         unlink($imagepath . $image_filename);
01061                                         $result = 1;
01062                                 }
01063                                 else
01064                                 {
01065                                         // create thumbnail file
01066                                         $thumbpath = $imagepath . $image_filename . "." . "thumb.jpg";
01067                                         ilUtil::convertImage($imagepath.$image_filename, $thumbpath, "JPEG", 100);
01068                                 }
01069                         }
01070                 }
01071                 return $result;
01072         }
01073 
01083         function checkSaveData()
01084         {
01085                 $result = true;
01086                 $matching_values = array();
01087                 foreach ($_POST as $key => $value)
01088                 {
01089                         if (preg_match("/^sel_matching_(\d+)/", $key, $matches))
01090                         {
01091                                 if ((strcmp($value, "") != 0) && ($value != -1))
01092                                 {
01093                                         array_push($matching_values, $value);
01094                                 }
01095                         }
01096                 }
01097                 $check_matching = array_flip($matching_values);
01098                 if (count($check_matching) != count($matching_values))
01099                 {
01100                         // duplicate matching values!!!
01101                         $result = false;
01102                         sendInfo($this->lng->txt("duplicate_matching_values_selected"), TRUE);
01103                 }
01104                 return $result;
01105         }
01106 
01117         function saveWorkingData($test_id, $pass = NULL)
01118         {
01119                 global $ilDB;
01120                 global $ilUser;
01121                 $saveWorkingDataResult = $this->checkSaveData();
01122                 $entered_values = 0;
01123                 if ($saveWorkingDataResult)
01124                 {
01125                         $db =& $ilDB->db;
01126         
01127                         include_once ("./assessment/classes/class.ilObjTest.php");
01128                         $activepass = ilObjTest::_getPass($ilUser->id, $test_id);
01129                         
01130                         $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
01131                                 $db->quote($ilUser->id . ""),
01132                                 $db->quote($test_id . ""),
01133                                 $db->quote($this->getId() . ""),
01134                                 $db->quote($activepass . "")
01135                         );
01136                         $result = $db->query($query);
01137                         foreach ($_POST as $key => $value)
01138                         {
01139                                 if (preg_match("/^sel_matching_(\d+)/", $key, $matches))
01140                                 {
01141                                         if (!(preg_match("/initial_value_\d+/", $value)))
01142                                         {
01143                                                 if ($value > -1) // -1 is the unselected value in the non javascript version
01144                                                 {
01145                                                         $entered_values++;
01146                                                         $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
01147                                                                 $db->quote($ilUser->id),
01148                                                                 $db->quote($test_id),
01149                                                                 $db->quote($this->getId()),
01150                                                                 $db->quote($value),
01151                                                                 $db->quote($matches[1]),
01152                                                                 $db->quote($activepass . "")
01153                                                         );
01154                                                         $result = $db->query($query);
01155                                                 }
01156                                         }
01157                                 }
01158                         }
01159                         $saveWorkingDataResult = true;
01160                 }
01161                 if ($entered_values)
01162                 {
01163                         include_once ("./classes/class.ilObjAssessmentFolder.php");
01164                         if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01165                         {
01166                                 $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $test_id, $this->getId());
01167                         }
01168                 }
01169                 else
01170                 {
01171                         include_once ("./classes/class.ilObjAssessmentFolder.php");
01172                         if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01173                         {
01174                                 $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $test_id, $this->getId());
01175                         }
01176                 }
01177     parent::saveWorkingData($test_id, $pass);
01178                 return $saveWorkingDataResult;
01179         }
01180 
01181         function get_random_id()
01182         {
01183                 mt_srand((double)microtime()*1000000);
01184                 $random_number = mt_rand(1, 100000);
01185                 $found = FALSE;
01186                 while ($found)
01187                 {
01188                         $found = FALSE;
01189                         foreach ($this->matchingpairs as $key => $value)
01190                         {
01191                                 if (($value->getTermId() == $random_number) || ($value->getDefinitionId() == $random_number))
01192                                 {
01193                                         $found = TRUE;
01194                                         $random_number++;
01195                                 }
01196                         }
01197                 }
01198                 return $random_number;
01199         }
01200 
01201         function syncWithOriginal()
01202         {
01203                 global $ilias;
01204                 if ($this->original_id)
01205                 {
01206                         $complete = 0;
01207                         if ($this->isComplete())
01208                         {
01209                                 $complete = 1;
01210                         }
01211                         $db = & $ilias->db;
01212         
01213                         $estw_time = $this->getEstimatedWorkingTime();
01214                         $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01215         
01216                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time=%s, matching_type = %s, points = %s, complete = %s WHERE question_id = %s",
01217                                 $db->quote($this->obj_id. ""),
01218                                 $db->quote($this->title. ""),
01219                                 $db->quote($this->comment. ""),
01220                                 $db->quote($this->author. ""),
01221                                 $db->quote($this->question. ""),
01222                                 $db->quote($estw_time. ""),
01223                                 $db->quote($this->matching_type. ""),
01224                                 $db->quote($this->getMaximumPoints() . ""),
01225                                 $db->quote($complete. ""),
01226                                 $db->quote($this->original_id. "")
01227                         );
01228                         $result = $db->query($query);
01229 
01230                         if ($result == DB_OK)
01231                         {
01232                                 // write answers
01233                                 // delete old answers
01234                                 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
01235                                         $db->quote($this->original_id)
01236                                 );
01237                                 $result = $db->query($query);
01238         
01239                                 foreach ($this->matchingpairs as $key => $value)
01240                                 {
01241                                         $matching_obj = $this->matchingpairs[$key];
01242                                         $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, matchingtext, matching_order, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
01243                                                 $db->quote($this->original_id . ""),
01244                                                 $db->quote($matching_obj->getTerm() . ""),
01245                                                 $db->quote($matching_obj->getPoints() . ""),
01246                                                 $db->quote($matching_obj->getTermId() . ""),
01247                                                 $db->quote($matching_obj->getDefinition() . ""),
01248                                                 $db->quote($matching_obj->getDefinitionId() . "")
01249                                         );
01250                                         $matching_result = $db->query($query);
01251                                 }
01252                         }
01253                         parent::syncWithOriginal();
01254                 }
01255         }
01256 
01257         function pc_array_shuffle($array) {
01258                 $i = count($array);
01259                 mt_srand((double)microtime()*1000000);
01260                 while(--$i) 
01261                 {
01262                         $j = mt_rand(0, $i);
01263                         if ($i != $j) 
01264                         {
01265                                 // swap elements
01266                                 $tmp = $array[$j];
01267                                 $array[$j] = $array[$i];
01268                                 $array[$i] = $tmp;
01269                         }
01270                 }
01271                 return $array;
01272         }
01273         
01274         function createRandomSolution($test_id, $user_id, $pass = NULL)
01275         {
01276                 global $ilDB;
01277                 global $ilUser;
01278                 $db =& $ilDB->db;
01279 
01280                 if (is_null($pass))
01281                 {
01282                         $pass = $this->getSolutionMaxPass($user_id, $test_id);
01283                 }
01284                 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
01285                         $db->quote($user_id),
01286                         $db->quote($test_id),
01287                         $db->quote($this->getId()),
01288                         $db->quote($pass . "")
01289                 );
01290                 $result = $db->query($query);
01291 
01292                 $terms = array();
01293                 $definitions = array();
01294                 
01295                 foreach ($this->matchingpairs as $key => $pair)
01296                 {
01297                         array_push($terms, $pair->getTermId());
01298                         array_push($definitions, $pair->getDefinitionId());
01299                 }
01300                 $definitions = $this->pc_array_shuffle($definitions);
01301                 foreach ($terms as $key => $value)
01302                 {
01303                         $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
01304                                 $db->quote($user_id),
01305                                 $db->quote($test_id),
01306                                 $db->quote($this->getId()),
01307                                 $db->quote($value),
01308                                 $db->quote($definitions[$key]),
01309                                 $db->quote($pass . "")
01310                         );
01311                         $result = $db->query($query);
01312                 }
01313         }
01314 
01323         function getQuestionType()
01324         {
01325                 return 4;
01326         }
01327         
01328 }
01329 
01330 ?>

Generated on Fri Dec 13 2013 11:57:52 for ILIAS Release_3_6_x_branch .rev 46809 by  doxygen 1.7.1