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

Modules/TestQuestionPool/classes/class.assTextSubset.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 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
00024 include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
00025 
00037 class assTextSubset extends assQuestion
00038 {
00046         var $answers;
00047         
00055         var $correctanswers;
00056 
00064         var $text_rating;
00065 
00079         function assTextSubset(
00080                 $title = "",
00081                 $comment = "",
00082                 $author = "",
00083                 $owner = -1,
00084                 $question = ""
00085           )
00086         {
00087                 $this->assQuestion($title, $comment, $author, $owner, $question);
00088                 $this->answers = array();
00089                 $this->correctanswers = 0;
00090         }
00091 
00100         function isComplete()
00101         {
00102                 if (($this->title) and ($this->author) and ($this->question) and (count($this->answers) >= $this->correctanswers) and ($this->getMaximumPoints() > 0))
00103                 {
00104                         return true;
00105                 }
00106                         else
00107                 {
00108                         return false;
00109                 }
00110         }
00111 
00120         function saveToDb($original_id = "")
00121         {
00122                 global $ilDB;
00123 
00124                 $complete = 0;
00125                 if ($this->isComplete())
00126                 {
00127                         $complete = 1;
00128                 }
00129                 $estw_time = $this->getEstimatedWorkingTime();
00130                 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00131 
00132                 if ($original_id)
00133                 {
00134                         $original_id = $ilDB->quote($original_id);
00135                 }
00136                 else
00137                 {
00138                         $original_id = "NULL";
00139                 }
00140 
00141                 // cleanup RTE images which are not inserted into the question text
00142                 include_once("./Services/RTE/classes/class.ilRTE.php");
00143                 if ($this->id == -1)
00144                 {
00145                         // Neuen Datensatz schreiben
00146                         $now = getdate();
00147                         $question_type = $this->getQuestionTypeID();
00148                         $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00149                         $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, points, working_time, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00150                                 $ilDB->quote($question_type),
00151                                 $ilDB->quote($this->obj_id),
00152                                 $ilDB->quote($this->title),
00153                                 $ilDB->quote($this->comment),
00154                                 $ilDB->quote($this->author),
00155                                 $ilDB->quote($this->owner),
00156                                 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($this->question, 0)),
00157                                 $ilDB->quote($this->getMaximumPoints() . ""),
00158                                 $ilDB->quote($estw_time),
00159                                 $ilDB->quote("$complete"),
00160                                 $ilDB->quote($created),
00161                                 $original_id
00162                         );
00163                         $result = $ilDB->query($query);
00164                         
00165                         if ($result == DB_OK)
00166                         {
00167                                 $this->id = $ilDB->getLastInsertId();
00168                                 $query = sprintf("INSERT INTO qpl_question_textsubset (question_fi, textgap_rating, correctanswers) VALUES (%s, %s, %s)",
00169                                         $ilDB->quote($this->id . ""),
00170                                         $ilDB->quote($this->getTextRating() . ""),
00171                                         $ilDB->quote($this->getCorrectAnswers() . "")
00172                                 );
00173                                 $ilDB->query($query);
00174 
00175                                 // create page object of question
00176                                 $this->createPageObject();
00177 
00178                                 // Falls die Frage in einen Test eingefügt werden soll, auch diese Verbindung erstellen
00179                                 if ($this->getTestId() > 0)
00180                                 {
00181                                 $this->insertIntoTest($this->getTestId());
00182                                 }
00183                         }
00184                 }
00185                 else
00186                 {
00187                         // Vorhandenen Datensatz aktualisieren
00188                         $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, points = %s, working_time=%s, complete = %s WHERE question_id = %s",
00189                                 $ilDB->quote($this->obj_id. ""),
00190                                 $ilDB->quote($this->title),
00191                                 $ilDB->quote($this->comment),
00192                                 $ilDB->quote($this->author),
00193                                 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($this->question, 0)),
00194                                 $ilDB->quote($this->getMaximumPoints() . ""),
00195                                 $ilDB->quote($estw_time),
00196                                 $ilDB->quote("$complete"),
00197                                 $ilDB->quote($this->id)
00198                         );
00199                         $result = $ilDB->query($query);
00200                         $query = sprintf("UPDATE qpl_question_textsubset SET textgap_rating = %s, correctanswers = %s WHERE question_fi = %s",
00201                                 $ilDB->quote($this->getTextRating() . ""),
00202                                 $ilDB->quote($this->getCorrectAnswers() . ""),
00203                                 $ilDB->quote($this->id . "")
00204                         );
00205                         $result = $ilDB->query($query);
00206                 }
00207                 if ($result == DB_OK)
00208                 {
00209                         // Write Ranges to the database
00210                         
00211                         // 1. delete old ranges
00212                         $query = sprintf("DELETE FROM qpl_answer_textsubset WHERE question_fi = %s",
00213                                 $ilDB->quote($this->id)
00214                         );
00215                         $result = $ilDB->query($query);
00216 
00217                         // 2. write ranges
00218                         foreach ($this->answers as $key => $value)
00219                         {
00220                                 $answer_obj = $this->answers[$key];
00221                                 $query = sprintf("INSERT INTO qpl_answer_textsubset (answer_id, question_fi, answertext, points, aorder) VALUES (NULL, %s, %s, %s, %s)",
00222                                         $ilDB->quote($this->id),
00223                                         $ilDB->quote($answer_obj->getAnswertext()),
00224                                         $ilDB->quote($answer_obj->getPoints() . ""),
00225                                         $ilDB->quote($answer_obj->getOrder() . "")
00226                                 );
00227                                 $answer_result = $ilDB->query($query);
00228                         }
00229                 }
00230                 parent::saveToDb($original_id);
00231         }
00232 
00242         function loadFromDb($question_id)
00243         {
00244                 global $ilDB;
00245 
00246     $query = sprintf("SELECT qpl_questions.*, qpl_question_textsubset.* FROM qpl_questions, qpl_question_textsubset WHERE question_id = %s AND qpl_questions.question_id = qpl_question_textsubset.question_fi",
00247                         $ilDB->quote($question_id)
00248                 );
00249                 $result = $ilDB->query($query);
00250                 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00251                 {
00252                         if ($result->numRows() == 1)
00253                         {
00254                                 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00255                                 $this->id = $question_id;
00256                                 $this->title = $data->title;
00257                                 $this->comment = $data->comment;
00258                                 $this->solution_hint = $data->solution_hint;
00259                                 $this->original_id = $data->original_id;
00260                                 $this->obj_id = $data->obj_fi;
00261                                 $this->author = $data->author;
00262                                 $this->owner = $data->owner;
00263                                 $this->points = $data->points;
00264                                 include_once("./Services/RTE/classes/class.ilRTE.php");
00265                                 $this->question = ilRTE::_replaceMediaObjectImageSrc($data->question_text, 1);
00266                                 $this->correctanswers = $data->correctanswers;
00267                                 $this->text_rating = $data->textgap_rating;
00268                                 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00269                         }
00270 
00271                         $query = sprintf("SELECT * FROM qpl_answer_textsubset WHERE question_fi = %s ORDER BY aorder ASC",
00272                                 $ilDB->quote($question_id)
00273                         );
00274                         $result = $ilDB->query($query);
00275 
00276                         include_once "./Modules/TestQuestionPool/classes/class.assAnswerSimple.php";
00277                         if (strcmp(strtolower(get_class($result)), db_result) == 0)
00278                         {
00279                                 while ($data = $result->fetchRow(DB_FETCHMODE_ASSOC))
00280                                 {
00281                                         array_push($this->answers, new ASS_AnswerSimple($data["answertext"], $data["points"], $data["aorder"]));
00282                                 }
00283                         }
00284                 }
00285                 parent::loadFromDb($question_id);
00286         }
00287 
00295         function addAnswer($answertext, $points, $answerorder)
00296         {
00297                 include_once "./Modules/TestQuestionPool/classes/class.assAnswerSimple.php";
00298                 array_push($this->answers, new ASS_AnswerSimple($answertext, $points, $answerorder));
00299         }
00300         
00308         function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00309         {
00310                 if ($this->id <= 0)
00311                 {
00312                         // The question has not been saved. It cannot be duplicated
00313                         return;
00314                 }
00315                 // duplicate the question in database
00316                 $this_id = $this->getId();
00317                 $clone = $this;
00318                 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
00319                 $original_id = assQuestion::_getOriginalId($this->id);
00320                 $clone->id = -1;
00321                 if ($title)
00322                 {
00323                         $clone->setTitle($title);
00324                 }
00325 
00326                 if ($author)
00327                 {
00328                         $clone->setAuthor($author);
00329                 }
00330                 if ($owner)
00331                 {
00332                         $clone->setOwner($owner);
00333                 }
00334 
00335                 if ($for_test)
00336                 {
00337                         $clone->saveToDb($original_id);
00338                 }
00339                 else
00340                 {
00341                         $clone->saveToDb();
00342                 }
00343 
00344                 // copy question page content
00345                 $clone->copyPageOfQuestion($this_id);
00346                 // copy XHTML media objects
00347                 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
00348                 // duplicate the generic feedback
00349                 $clone->duplicateFeedbackGeneric($this_id);
00350 
00351                 return $clone->id;
00352         }
00353 
00361         function copyObject($target_questionpool, $title = "")
00362         {
00363                 if ($this->id <= 0)
00364                 {
00365                         // The question has not been saved. It cannot be duplicated
00366                         return;
00367                 }
00368                 // duplicate the question in database
00369                 $clone = $this;
00370                 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
00371                 $original_id = assQuestion::_getOriginalId($this->id);
00372                 $clone->id = -1;
00373                 $source_questionpool = $this->getObjId();
00374                 $clone->setObjId($target_questionpool);
00375                 if ($title)
00376                 {
00377                         $clone->setTitle($title);
00378                 }
00379                 $clone->saveToDb();
00380 
00381                 // copy question page content
00382                 $clone->copyPageOfQuestion($original_id);
00383                 // copy XHTML media objects
00384                 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
00385                 // duplicate the generic feedback
00386                 $clone->duplicateFeedbackGeneric($original_id);
00387 
00388                 return $clone->id;
00389         }
00390         
00400         function getAnswerCount()
00401         {
00402                 return count($this->answers);
00403         }
00404 
00416         function getAnswer($index = 0)
00417         {
00418                 if ($index < 0) return NULL;
00419                 if (count($this->answers) < 1) return NULL;
00420                 if ($index >= count($this->answers)) return NULL;
00421 
00422                 return $this->answers[$index];
00423         }
00424 
00435         function deleteAnswer($index = 0)
00436         {
00437                 if ($index < 0) return;
00438                 if (count($this->answers) < 1) return;
00439                 if ($index >= count($this->answers)) return;
00440                 unset($this->answers[$index]);
00441                 $this->answers = array_values($this->answers);
00442                 for ($i = 0; $i < count($this->answers); $i++)
00443                 {
00444                         if ($this->answers[$i]->getOrder() > $index)
00445                         {
00446                                 $this->answers[$i]->setOrder($i);
00447                         }
00448                 }
00449         }
00450 
00459         function flushAnswers()
00460         {
00461                 $this->answers = array();
00462         }
00463 
00472         function getMaximumPoints()
00473         {
00474                 $points = array();
00475                 foreach ($this->answers as $answer)
00476                 {
00477                         if ($answer->getPoints() > 0)
00478                         {
00479                                 array_push($points, $answer->getPoints());
00480                         }
00481                 }
00482                 rsort($points, SORT_NUMERIC);
00483                 $maxpoints = 0;
00484                 for ($counter = 0; $counter < $this->getCorrectAnswers(); $counter++)
00485                 {
00486                         $maxpoints += $points[$counter];
00487                 }
00488                 return $maxpoints;
00489         }
00490         
00499         function &getAvailableAnswers()
00500         {
00501                 $available_answers = array();
00502                 foreach ($this->answers as $answer)
00503                 {
00504                         array_push($available_answers, $answer->getAnswertext());
00505                 }
00506                 return $available_answers;
00507         }
00508 
00521         function isAnswerCorrect($answers, $answer)
00522         {
00523                 include_once "./Services/Utilities/classes/class.ilStr.php";
00524                 $result = 0;
00525                 $textrating = $this->getTextRating();
00526                 foreach ($answers as $key => $value)
00527                 {
00528                         switch ($textrating)
00529                         {
00530                                 case TEXTGAP_RATING_CASEINSENSITIVE:
00531                                         if (strcmp(ilStr::strToLower($value), ilStr::strToLower($answer)) == 0) return $key;
00532                                         break;
00533                                 case TEXTGAP_RATING_CASESENSITIVE:
00534                                         if (strcmp($value, $answer) == 0) return $key;
00535                                         break;
00536                                 case TEXTGAP_RATING_LEVENSHTEIN1:
00537                                         if (levenshtein($value, $answer) <= 1) return $key;
00538                                         break;
00539                                 case TEXTGAP_RATING_LEVENSHTEIN2:
00540                                         if (levenshtein($value, $answer) <= 2) return $key;
00541                                         break;
00542                                 case TEXTGAP_RATING_LEVENSHTEIN3:
00543                                         if (levenshtein($value, $answer) <= 3) return $key;
00544                                         break;
00545                                 case TEXTGAP_RATING_LEVENSHTEIN4:
00546                                         if (levenshtein($value, $answer) <= 4) return $key;
00547                                         break;
00548                                 case TEXTGAP_RATING_LEVENSHTEIN5:
00549                                         if (levenshtein($value, $answer) <= 5) return $key;
00550                                         break;
00551                         }
00552                 }
00553                 return FALSE;
00554         }
00555 
00565         function getTextRating()
00566         {
00567                 return $this->text_rating;
00568         }
00569         
00579         function setTextRating($a_text_rating)
00580         {
00581                 switch ($a_text_rating)
00582                 {
00583                         case TEXTGAP_RATING_CASEINSENSITIVE:
00584                         case TEXTGAP_RATING_CASESENSITIVE:
00585                         case TEXTGAP_RATING_LEVENSHTEIN1:
00586                         case TEXTGAP_RATING_LEVENSHTEIN2:
00587                         case TEXTGAP_RATING_LEVENSHTEIN3:
00588                         case TEXTGAP_RATING_LEVENSHTEIN4:
00589                         case TEXTGAP_RATING_LEVENSHTEIN5:
00590                                 $this->text_rating = $a_text_rating;
00591                                 break;
00592                         default:
00593                                 $this->text_rating = TEXTGAP_RATING_CASEINSENSITIVE;
00594                                 break;
00595                 }
00596         }
00597         
00609         function calculateReachedPoints($active_id, $pass = NULL)
00610         {
00611                 global $ilDB;
00612                 
00613                 $available_answers =& $this->getAvailableAnswers();
00614                 $found_counter = 0;
00615                 
00616                 if (is_null($pass))
00617                 {
00618                         $pass = $this->getSolutionMaxPass($active_id);
00619                 }
00620                 $query = sprintf("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
00621                         $ilDB->quote($active_id . ""),
00622                         $ilDB->quote($this->getId() . ""),
00623                         $ilDB->quote($pass . "")
00624                 );
00625                 $result = $ilDB->query($query);
00626                 $points = 0;
00627                 while ($data = $result->fetchRow(DB_FETCHMODE_ASSOC))
00628                 {
00629                         $enteredtext = $data["value1"];
00630                         $index = $this->isAnswerCorrect($available_answers, $enteredtext);
00631                         if ($index !== FALSE)
00632                         {
00633                                 unset($available_answers[$index]);
00634                                 $points += $this->answers[$index]->getPoints();
00635                         }
00636                 }
00637 
00638                 $points = parent::calculateReachedPoints($active_id, $pass = NULL, $points);
00639                 return $points;
00640         }
00641         
00650         function setCorrectAnswers($a_correct_answers)
00651         {
00652                 $this->correctanswers = $a_correct_answers;
00653         }
00654         
00663         function getCorrectAnswers()
00664         {
00665                 return $this->correctanswers;
00666         }
00667         
00678         function saveWorkingData($active_id, $pass = NULL)
00679         {
00680                 global $ilDB;
00681                 global $ilUser;
00682 
00683                 if (is_null($pass))
00684                 {
00685                         include_once "./Modules/Test/classes/class.ilObjTest.php";
00686                         $pass = ilObjTest::_getPass($active_id);
00687                 }
00688                 $entered_values = 0;
00689                 
00690                 $query = sprintf("DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
00691                         $ilDB->quote($active_id . ""),
00692                         $ilDB->quote($this->getId() . ""),
00693                         $ilDB->quote($pass . "")
00694                 );
00695                 $result = $ilDB->query($query);
00696                 foreach ($_POST as $key => $value)
00697                 {
00698                         if (preg_match("/^TEXTSUBSET_(\d+)/", $key, $matches))
00699                         {
00700                                 if (strlen($value))
00701                                 {
00702                                         $query = sprintf("INSERT INTO tst_solutions (solution_id, active_fi, question_fi, value1, value2, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL, %s, NULL)",
00703                                                 $ilDB->quote($active_id),
00704                                                 $ilDB->quote($this->getId()),
00705                                                 $ilDB->quote(trim($value)),
00706                                                 $ilDB->quote($pass . "")
00707                                         );
00708                                         $result = $ilDB->query($query);
00709                                         $entered_values++;
00710                                 }
00711                         }
00712                 }
00713                 if ($entered_values)
00714                 {
00715                         include_once ("./classes/class.ilObjAssessmentFolder.php");
00716                         if (ilObjAssessmentFolder::_enabledAssessmentLogging())
00717                         {
00718                                 $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
00719                         }
00720                 }
00721                 else
00722                 {
00723                         include_once ("./classes/class.ilObjAssessmentFolder.php");
00724                         if (ilObjAssessmentFolder::_enabledAssessmentLogging())
00725                         {
00726                                 $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
00727                         }
00728                 }
00729     parent::saveWorkingData($active_id, $pass);
00730                 return true;
00731         }
00732 
00741         function getQuestionType()
00742         {
00743                 return "assTextSubset";
00744         }
00745         
00754         function &joinAnswers()
00755         {
00756                 $join = array();
00757                 foreach ($this->answers as $answer)
00758                 {
00759                         if (!is_array($join[$answer->getPoints() . ""]))
00760                         {
00761                                 $join[$answer->getPoints() . ""] = array();
00762                         }
00763                         array_push($join[$answer->getPoints() . ""], $answer->getAnswertext());
00764                 }
00765                 return $join;
00766         }
00767         
00776         function getMaxTextboxWidth()
00777         {
00778                 $maxwidth = 0;
00779                 foreach ($this->answers as $answer)
00780                 {
00781                         $len = strlen($answer->getAnswertext());
00782                         if ($len > $maxwidth) $maxwidth = $len;
00783                 }
00784                 return $maxwidth + 3;
00785         }
00786 
00795         function getAdditionalTableName()
00796         {
00797                 return "qpl_question_textsubset";
00798         }
00799 
00808         function getAnswerTableName()
00809         {
00810                 return "qpl_answer_textsubset";
00811         }
00812 
00817         function getRTETextWithMediaObjects()
00818         {
00819                 return parent::getRTETextWithMediaObjects();
00820         }
00821 }
00822 
00823 ?>

Generated on Fri Dec 13 2013 17:56:54 for ILIAS Release_3_9_x_branch .rev 46835 by  doxygen 1.7.1