00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
00024 include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
00025
00035 class assTextQuestion extends assQuestion
00036 {
00044 var $maxNumOfChars;
00045
00054 var $keywords;
00055
00063 var $text_rating;
00064
00078 function assTextQuestion(
00079 $title = "",
00080 $comment = "",
00081 $author = "",
00082 $owner = -1,
00083 $question = ""
00084 )
00085 {
00086 $this->assQuestion($title, $comment, $author, $owner, $question);
00087 $this->maxNumOfChars = 0;
00088 $this->points = 0;
00089 $this->keywords = "";
00090 }
00091
00100 function isComplete()
00101 {
00102 if (($this->title) and ($this->author) and ($this->question) 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
00142 include_once("./Services/RTE/classes/class.ilRTE.php");
00143 if ($this->id == -1)
00144 {
00145
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, points, question_text, 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($this->getPoints() . ""),
00157 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($this->question, 0)),
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_essay (question_fi, maxNumOfChars, keywords, textgap_rating) VALUES (%s, %s, %s, %s)",
00169 $ilDB->quote($this->id . ""),
00170 $ilDB->quote($this->getMaxNumOfChars()),
00171 $ilDB->quote($this->getKeywords() . ""),
00172 $ilDB->quote($this->getTextRating() . "")
00173 );
00174 $ilDB->query($query);
00175
00176
00177 $this->createPageObject();
00178
00179 if ($this->getTestId() > 0)
00180 {
00181 $this->insertIntoTest($this->getTestId());
00182 }
00183 }
00184 }
00185 else
00186 {
00187
00188 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, points = %s, question_text = %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($this->getPoints() . ""),
00194 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($this->question, 0)),
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_essay SET maxNumOfChars = %s, keywords = %s, textgap_rating = %s WHERE question_fi = %s",
00201 $ilDB->quote($this->getMaxNumOfChars()),
00202 $ilDB->quote($this->getKeywords() . ""),
00203 $ilDB->quote($this->getTextRating() . ""),
00204 $ilDB->quote($this->id . "")
00205 );
00206 $result = $ilDB->query($query);
00207 }
00208 parent::saveToDb($original_id);
00209 }
00210
00220 function loadFromDb($question_id)
00221 {
00222 global $ilDB;
00223
00224 $query = sprintf("SELECT qpl_questions.*, qpl_question_essay.* FROM qpl_questions, qpl_question_essay WHERE question_id = %s AND qpl_questions.question_id = qpl_question_essay.question_fi",
00225 $ilDB->quote($question_id)
00226 );
00227 $result = $ilDB->query($query);
00228 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00229 {
00230 if ($result->numRows() == 1)
00231 {
00232 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00233 $this->id = $question_id;
00234 $this->title = $data->title;
00235 $this->comment = $data->comment;
00236 $this->solution_hint = $data->solution_hint;
00237 $this->original_id = $data->original_id;
00238 $this->obj_id = $data->obj_fi;
00239 $this->author = $data->author;
00240 $this->owner = $data->owner;
00241 include_once("./Services/RTE/classes/class.ilRTE.php");
00242 $this->question = ilRTE::_replaceMediaObjectImageSrc($data->question_text, 1);
00243 $this->maxNumOfChars = $data->maxNumOfChars;
00244 $this->keywords = $data->keywords;
00245 $this->text_rating = $data->textgap_rating;
00246 $this->points = $data->points;
00247 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00248 }
00249 }
00250 parent::loadFromDb($question_id);
00251 }
00252
00260 function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00261 {
00262 if ($this->id <= 0)
00263 {
00264
00265 return;
00266 }
00267
00268 $this_id = $this->getId();
00269 $clone = $this;
00270 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
00271 $original_id = assQuestion::_getOriginalId($this->id);
00272 $clone->id = -1;
00273 if ($title)
00274 {
00275 $clone->setTitle($title);
00276 }
00277
00278 if ($author)
00279 {
00280 $clone->setAuthor($author);
00281 }
00282 if ($owner)
00283 {
00284 $clone->setOwner($owner);
00285 }
00286
00287 if ($for_test)
00288 {
00289 $clone->saveToDb($original_id);
00290 }
00291 else
00292 {
00293 $clone->saveToDb();
00294 }
00295
00296
00297 $clone->copyPageOfQuestion($this_id);
00298
00299 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
00300
00301 $clone->duplicateFeedbackGeneric($this_id);
00302
00303 return $clone->id;
00304 }
00305
00313 function copyObject($target_questionpool, $title = "")
00314 {
00315 if ($this->id <= 0)
00316 {
00317
00318 return;
00319 }
00320
00321 $clone = $this;
00322 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
00323 $original_id = assQuestion::_getOriginalId($this->id);
00324 $clone->id = -1;
00325 $source_questionpool = $this->getObjId();
00326 $clone->setObjId($target_questionpool);
00327 if ($title)
00328 {
00329 $clone->setTitle($title);
00330 }
00331 $clone->saveToDb();
00332
00333
00334 $clone->copyPageOfQuestion($original_id);
00335
00336 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
00337
00338 $clone->duplicateFeedbackGeneric($original_id);
00339
00340 return $clone->id;
00341 }
00342
00352 function getMaxNumOfChars()
00353 {
00354 if (strcmp($this->maxNumOfChars, "") == 0)
00355 {
00356 return 0;
00357 }
00358 else
00359 {
00360 return $this->maxNumOfChars;
00361 }
00362 }
00363
00373 function setMaxNumOfChars($maxchars = 0)
00374 {
00375 $this->maxNumOfChars = $maxchars;
00376 }
00377
00386 function getMaximumPoints()
00387 {
00388 return $this->points;
00389 }
00390
00402 function setReachedPoints($active_id, $points, $pass = NULL)
00403 {
00404 global $ilDB;
00405
00406 if (($points > 0) && ($points <= $this->getPoints()))
00407 {
00408 if (is_null($pass))
00409 {
00410 $pass = $this->getSolutionMaxPass($active_id);
00411 }
00412 $query = sprintf("UPDATE tst_test_result SET points = %s WHERE active_fi = %s AND question_fi = %s AND pass = %s",
00413 $ilDB->quote($points . ""),
00414 $ilDB->quote($active_id . ""),
00415 $ilDB->quote($this->getId() . ""),
00416 $ilDB->quote($pass . "")
00417 );
00418 $result = $ilDB->query($query);
00419 $this->_updateTestPassResults($active_id, $pass);
00420 return TRUE;
00421 }
00422 else
00423 {
00424 return TRUE;
00425 }
00426 }
00427
00438 function isKeywordMatching($answertext, $a_keyword)
00439 {
00440 $result = FALSE;
00441 $textrating = $this->getTextRating();
00442 include_once "./Services/Utilities/classes/class.ilStr.php";
00443 switch ($textrating)
00444 {
00445 case TEXTGAP_RATING_CASEINSENSITIVE:
00446 if (ilStr::strPos(ilStr::strToLower($answertext), ilStr::strToLower($a_keyword)) !== false) return TRUE;
00447 break;
00448 case TEXTGAP_RATING_CASESENSITIVE:
00449 if (ilStr::strPos($answertext, $a_keyword) !== false) return TRUE;
00450 break;
00451 }
00452 $answerwords = array();
00453 if (preg_match_all("/([^\s.]+)/", $answertext, $matches))
00454 {
00455 foreach ($matches[1] as $answerword)
00456 {
00457 array_push($answerwords, trim($answerword));
00458 }
00459 }
00460 foreach ($answerwords as $a_original)
00461 {
00462 switch ($textrating)
00463 {
00464 case TEXTGAP_RATING_LEVENSHTEIN1:
00465 if (levenshtein($a_original, $a_keyword) <= 1) return TRUE;
00466 break;
00467 case TEXTGAP_RATING_LEVENSHTEIN2:
00468 if (levenshtein($a_original, $a_keyword) <= 2) return TRUE;
00469 break;
00470 case TEXTGAP_RATING_LEVENSHTEIN3:
00471 if (levenshtein($a_original, $a_keyword) <= 3) return TRUE;
00472 break;
00473 case TEXTGAP_RATING_LEVENSHTEIN4:
00474 if (levenshtein($a_original, $a_keyword) <= 4) return TRUE;
00475 break;
00476 case TEXTGAP_RATING_LEVENSHTEIN5:
00477 if (levenshtein($a_original, $a_keyword) <= 5) return TRUE;
00478 break;
00479 }
00480 }
00481 return $result;
00482 }
00483
00495 function calculateReachedPoints($active_id, $pass = NULL)
00496 {
00497 global $ilDB;
00498
00499 $points = 0;
00500 if (is_null($pass))
00501 {
00502 $pass = $this->getSolutionMaxPass($active_id);
00503 }
00504 $query = sprintf("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
00505 $ilDB->quote($active_id . ""),
00506 $ilDB->quote($this->getId() . ""),
00507 $ilDB->quote($pass . "")
00508 );
00509 $result = $ilDB->query($query);
00510 if ($result->numRows() == 1)
00511 {
00512 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00513 if ($row["points"])
00514 {
00515 $points = $row["points"];
00516 }
00517 else
00518 {
00519 $keywords =& $this->getKeywordList();
00520 if (count($keywords))
00521 {
00522 $foundkeyword = false;
00523 foreach ($keywords as $keyword)
00524 {
00525 if (!$foundkeyword)
00526 {
00527 if ($this->isKeywordMatching($row["value1"], $keyword))
00528 {
00529 $foundkeyword = true;
00530 }
00531 }
00532 }
00533 if ($foundkeyword) $points = $this->getMaximumPoints();
00534 }
00535 }
00536 }
00537
00538 $points = parent::calculateReachedPoints($active_id, $pass = NULL, $points);
00539 return $points;
00540 }
00541
00552 function saveWorkingData($active_id, $pass = NULL)
00553 {
00554 global $ilDB;
00555 global $ilUser;
00556
00557 if (is_null($pass))
00558 {
00559 include_once "./Modules/Test/classes/class.ilObjTest.php";
00560 $pass = ilObjTest::_getPass($active_id);
00561 }
00562
00563 $query = sprintf("DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
00564 $ilDB->quote($active_id . ""),
00565 $ilDB->quote($this->getId() . ""),
00566 $ilDB->quote($pass . "")
00567 );
00568 $result = $ilDB->query($query);
00569
00570 $text = ilUtil::stripSlashes($_POST["TEXT"], FALSE);
00571 if ($this->getMaxNumOfChars())
00572 {
00573 include_once "./Services/Utilities/classes/class.ilStr.php";
00574 $text = ilStr::subStr($text, 0, $this->getMaxNumOfChars());
00575 }
00576 $entered_values = 0;
00577 if (strlen($text))
00578 {
00579 $query = sprintf("INSERT INTO tst_solutions (solution_id, active_fi, question_fi, value1, value2, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL, %s, NULL)",
00580 $ilDB->quote($active_id . ""),
00581 $ilDB->quote($this->getId() . ""),
00582 $ilDB->quote(trim($text) . ""),
00583 $ilDB->quote($pass . "")
00584 );
00585 $result = $ilDB->query($query);
00586 $entered_values++;
00587 }
00588 if ($entered_values)
00589 {
00590 include_once ("./classes/class.ilObjAssessmentFolder.php");
00591 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
00592 {
00593 $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
00594 }
00595 }
00596 else
00597 {
00598 include_once ("./classes/class.ilObjAssessmentFolder.php");
00599 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
00600 {
00601 $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
00602 }
00603 }
00604 parent::saveWorkingData($active_id, $pass);
00605 return true;
00606 }
00607
00608 function createRandomSolution($test_id, $user_id)
00609 {
00610 }
00611
00620 function getQuestionType()
00621 {
00622 return "assTextQuestion";
00623 }
00624
00633 function getKeywords()
00634 {
00635 return $this->keywords;
00636 }
00637
00646 function setKeywords($a_keywords)
00647 {
00648 $this->keywords = $a_keywords;
00649 }
00650
00659 function &getKeywordList()
00660 {
00661 $keywords = array();
00662 if (preg_match_all("/([^\s]+)/", $this->keywords, $matches))
00663 {
00664 foreach ($matches[1] as $keyword)
00665 {
00666 array_push($keywords, trim($keyword));
00667 }
00668 }
00669 return $keywords;
00670 }
00671
00681 function getTextRating()
00682 {
00683 return $this->text_rating;
00684 }
00685
00695 function setTextRating($a_text_rating)
00696 {
00697 switch ($a_text_rating)
00698 {
00699 case TEXTGAP_RATING_CASEINSENSITIVE:
00700 case TEXTGAP_RATING_CASESENSITIVE:
00701 case TEXTGAP_RATING_LEVENSHTEIN1:
00702 case TEXTGAP_RATING_LEVENSHTEIN2:
00703 case TEXTGAP_RATING_LEVENSHTEIN3:
00704 case TEXTGAP_RATING_LEVENSHTEIN4:
00705 case TEXTGAP_RATING_LEVENSHTEIN5:
00706 $this->text_rating = $a_text_rating;
00707 break;
00708 default:
00709 $this->text_rating = TEXTGAP_RATING_CASEINSENSITIVE;
00710 break;
00711 }
00712 }
00713
00722 function getAdditionalTableName()
00723 {
00724 return "qpl_question_essay";
00725 }
00726
00731 function getRTETextWithMediaObjects()
00732 {
00733 return parent::getRTETextWithMediaObjects();
00734 }
00735 }
00736
00737 ?>