ILIAS  eassessment Revision 61809
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.assNumeric.php
Go to the documentation of this file.
1 <?php
2  /*
3  +----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +----------------------------------------------------------------------------+
22 */
23 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
24 include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
25 
37 class assNumeric extends assQuestion
38 {
39  protected $lower_limit;
40  protected $upper_limit;
41 
47  var $maxchars;
48 
62  function __construct(
63  $title = "",
64  $comment = "",
65  $author = "",
66  $owner = -1,
67  $question = ""
68  )
69  {
71  $this->maxchars = 6;
72  }
73 
80  function isComplete()
81  {
82  if (($this->title) and ($this->author) and ($this->question) and ($this->getMaximumPoints() > 0))
83  {
84  return true;
85  }
86  else
87  {
88  return false;
89  }
90  }
91 
98  function saveToDb($original_id = "")
99  {
100  global $ilDB;
101 
103 
104  // save additional data
105  $affectedRows = $ilDB->manipulateF("DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
106  array("integer"),
107  array($this->getId())
108  );
109 
110  $affectedRows = $ilDB->manipulateF("INSERT INTO " . $this->getAdditionalTableName() . " (question_fi, maxnumofchars) VALUES (%s, %s)",
111  array("integer", "integer"),
112  array(
113  $this->getId(),
114  ($this->getMaxChars()) ? $this->getMaxChars() : 0
115  )
116  );
117 
118  // Write range to the database
119 
120  // 1. delete old range
121  $result = $ilDB->manipulateF("DELETE FROM qpl_num_range WHERE question_fi = %s",
122  array('integer'),
123  array($this->getId())
124  );
125 
126  // 2. write range
127  $next_id = $ilDB->nextId('qpl_num_range');
128  $answer_result = $ilDB->manipulateF("INSERT INTO qpl_num_range (range_id, question_fi, lowerlimit, upperlimit, points, aorder, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
129  array('integer','integer', 'text', 'text', 'float', 'integer', 'integer'),
130  array($next_id, $this->id, $this->getLowerLimit(), $this->getUpperLimit(), $this->getPoints(), 0, time())
131  );
132 
134  }
135 
143  function loadFromDb($question_id)
144  {
145  global $ilDB;
146 
147  $result = $ilDB->queryF("SELECT qpl_questions.*, " . $this->getAdditionalTableName() . ".* FROM qpl_questions LEFT JOIN " . $this->getAdditionalTableName() . " ON " . $this->getAdditionalTableName() . ".question_fi = qpl_questions.question_id WHERE qpl_questions.question_id = %s",
148  array("integer"),
149  array($question_id)
150  );
151  if ($result->numRows() == 1)
152  {
153  $data = $ilDB->fetchAssoc($result);
154  $this->setId($question_id);
155  $this->setObjId($data["obj_fi"]);
156  $this->setTitle($data["title"]);
157  $this->setComment($data["description"]);
158  $this->setNrOfTries($data['nr_of_tries']);
159  $this->setOriginalId($data["original_id"]);
160  $this->setAuthor($data["author"]);
161  $this->setPoints($data["points"]);
162  $this->setOwner($data["owner"]);
163  include_once("./Services/RTE/classes/class.ilRTE.php");
164  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
165  $this->setMaxChars($data["maxnumofchars"]);
166  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
167  }
168 
169 
170  $result = $ilDB->queryF("SELECT * FROM qpl_num_range WHERE question_fi = %s ORDER BY aorder ASC",
171  array('integer'),
172  array($question_id)
173  );
174 
175  include_once "./Modules/TestQuestionPool/classes/class.assNumericRange.php";
176  if ($result->numRows() > 0)
177  {
178  while ($data = $ilDB->fetchAssoc($result))
179  {
180  $this->setPoints($data['points']);
181  $this->setLowerLimit($data['lowerlimit']);
182  $this->setUpperLimit($data['upperlimit']);
183  }
184  }
185 
186  parent::loadFromDb($question_id);
187  }
188 
194  function duplicate($for_test = true, $title = "", $author = "", $owner = "")
195  {
196  if ($this->id <= 0)
197  {
198  // The question has not been saved. It cannot be duplicated
199  return;
200  }
201  // duplicate the question in database
202  $this_id = $this->getId();
203  $clone = $this;
204  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
206  $clone->id = -1;
207  if ($title)
208  {
209  $clone->setTitle($title);
210  }
211 
212  if ($author)
213  {
214  $clone->setAuthor($author);
215  }
216  if ($owner)
217  {
218  $clone->setOwner($owner);
219  }
220 
221  if ($for_test)
222  {
223  $clone->saveToDb($original_id);
224  }
225  else
226  {
227  $clone->saveToDb();
228  }
229 
230  // copy question page content
231  $clone->copyPageOfQuestion($this_id);
232  // copy XHTML media objects
233  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
234  // duplicate the generic feedback
235  $clone->duplicateFeedbackGeneric($this_id);
236 
237  $clone->onDuplicate($this_id);
238  return $clone->id;
239  }
240 
246  function copyObject($target_questionpool, $title = "")
247  {
248  if ($this->id <= 0)
249  {
250  // The question has not been saved. It cannot be duplicated
251  return;
252  }
253  // duplicate the question in database
254  $clone = $this;
255  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
257  $clone->id = -1;
258  $source_questionpool = $this->getObjId();
259  $clone->setObjId($target_questionpool);
260  if ($title)
261  {
262  $clone->setTitle($title);
263  }
264  $clone->saveToDb();
265 
266  // copy question page content
267  $clone->copyPageOfQuestion($original_id);
268  // copy XHTML media objects
269  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
270  // duplicate the generic feedback
271  $clone->duplicateFeedbackGeneric($original_id);
272 
273  $clone->onCopy($this->getObjId(), $this->getId());
274  return $clone->id;
275  }
276 
277  function getLowerLimit()
278  {
279  return $this->lower_limit;
280  }
281 
282  function getUpperLimit()
283  {
284  return $this->upper_limit;
285  }
286 
287  function setLowerLimit($a_limit)
288  {
289  $this->lower_limit = $a_limit;
290  }
291 
292  function setUpperLimit($a_limit)
293  {
294  $this->upper_limit = $a_limit;
295  }
296 
303  function getMaximumPoints()
304  {
305  return $this->getPoints();
306  }
307 
317  function calculateReachedPoints($active_id, $pass = NULL)
318  {
319  global $ilDB;
320 
321  $found_values = array();
322  if (is_null($pass))
323  {
324  $pass = $this->getSolutionMaxPass($active_id);
325  }
326  $result = $ilDB->queryF("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
327  array('integer','integer','integer'),
328  array($active_id, $this->getId(), $pass)
329  );
330  $data = $ilDB->fetchAssoc($result);
331 
332  $enteredvalue = $data["value1"];
333 
334  $points = 0;
335  if ($this->contains($enteredvalue))
336  {
337  $points = $this->getPoints();
338  }
339 
340  $points = parent::calculateReachedPoints($active_id, $pass = NULL, $points);
341  return $points;
342  }
343 
353  function contains($value)
354  {
355  include_once "./Services/Math/classes/class.EvalMath.php";
356  $eval = new EvalMath();
357  $eval->suppress_errors = TRUE;
358  $result = $eval->e($value);
359  if (($result === FALSE) || ($result === TRUE)) return FALSE;
360  if (($result >= $eval->e($this->getLowerLimit())) && ($result <= $eval->e($this->getUpperLimit())))
361  {
362  return TRUE;
363  }
364  else
365  {
366  return FALSE;
367  }
368  }
369 
376  function saveWorkingData($active_id, $pass = NULL)
377  {
378  global $ilDB;
379  global $ilUser;
380 
381  if (is_null($pass))
382  {
383  include_once "./Modules/Test/classes/class.ilObjTest.php";
384  $pass = ilObjTest::_getPass($active_id);
385  }
386  $entered_values = 0;
387  $numeric_result = str_replace(",",".",$_POST["numeric_result"]);
388 
389  include_once "./Services/Math/classes/class.EvalMath.php";
390  $math = new EvalMath();
391  $math->suppress_errors = TRUE;
392  $result = $math->evaluate($numeric_result);
393  $returnvalue = true;
394  if ((($result === FALSE) || ($result === TRUE)) && (strlen($result) > 0))
395  {
396  ilUtil::sendInfo($this->lng->txt("err_no_numeric_value"), true);
397  $returnvalue = false;
398  }
399  $result = $ilDB->queryF("SELECT solution_id FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
400  array('integer','integer','integer'),
401  array($active_id, $this->getId(), $pass)
402  );
403  $row = $ilDB->fetchAssoc($result);
404  $update = $row["solution_id"];
405  if ($update)
406  {
407  if (strlen($numeric_result))
408  {
409  $affectedRows = $ilDB->update("tst_solutions", array(
410  "value1" => array("clob", trim($numeric_result)),
411  "tstamp" => array("integer", time())
412  ), array(
413  "solution_id" => array("integer", $update)
414  ));
415  $entered_values++;
416  }
417  else
418  {
419  $affectedRows = $ilDB->manipulateF("DELETE FROM tst_solutions WHERE solution_id = %s",
420  array('integer'),
421  array($update)
422  );
423  }
424  }
425  else
426  {
427  if (strlen($numeric_result))
428  {
429  $next_id = $ilDB->nextId('tst_solutions');
430  $affectedRows = $ilDB->insert("tst_solutions", array(
431  "solution_id" => array("integer", $next_id),
432  "active_fi" => array("integer", $active_id),
433  "question_fi" => array("integer", $this->getId()),
434  "value1" => array("clob", trim($numeric_result)),
435  "value2" => array("clob", null),
436  "pass" => array("integer", $pass),
437  "tstamp" => array("integer", time())
438  ));
439  $entered_values++;
440  }
441  }
442  if ($entered_values)
443  {
444  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
446  {
447  $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
448  }
449  }
450  else
451  {
452  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
454  {
455  $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
456  }
457  }
458  parent::saveWorkingData($active_id, $pass);
459 
460  return $returnvalue;
461  }
462 
469  function getQuestionType()
470  {
471  return "assNumeric";
472  }
473 
480  function getMaxChars()
481  {
482  return $this->maxchars;
483  }
484 
492  {
493  $this->maxchars = $maxchars;
494  }
495 
503  {
504  return "qpl_qst_numeric";
505  }
506 
512  {
514  }
515 
525  public function setExportDetailsXLS(&$adapter, $startrow, $active_id, $pass)
526  {
527  $solutions = $this->getSolutionValues($active_id, $pass);
528  $adapter->setCellValue($startrow, 0, $this->lng->txt($this->getQuestionType()), CELL_FORMAT_TITLE);
529  $adapter->setCellValue($startrow, 1, $this->getTitle(), CELL_FORMAT_TITLE);
530  $i = 1;
531  $adapter->setCellValue($startrow + $i, 0, $this->lng->txt("result"), CELL_FORMAT_BOLD);
532  if (strlen($solutions[0]["value1"]))
533  {
534  $adapter->setCellValue($startrow + $i, 1, $solutions[0]["value1"]);
535  }
536  $i++;
537  return $startrow + $i + 1;
538  }
539 }
540 
541 ?>