ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.assNumeric.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 require_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
5 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
6 require_once './Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
7 require_once './Modules/TestQuestionPool/interfaces/interface.ilObjAnswerScoringAdjustable.php';
8 
25 {
26  protected $lower_limit;
27  protected $upper_limit;
28 
30  var $maxchars;
31 
43  function __construct(
44  $title = "",
45  $comment = "",
46  $author = "",
47  $owner = -1,
48  $question = ""
49  )
50  {
52  $this->maxchars = 6;
53  }
54 
60  public function isComplete()
61  {
62  if (
63  strlen($this->title)
64  && $this->author
65  && $this->question
66  && $this->getMaximumPoints() > 0
67  )
68  {
69  return true;
70  }
71  return false;
72  }
73 
79  public function saveToDb($original_id = "")
80  {
85  }
86 
92  public function loadFromDb($question_id)
93  {
95  global $ilDB;
96 
97  $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",
98  array("integer"),
99  array($question_id)
100  );
101  if ($result->numRows() == 1)
102  {
103  $data = $ilDB->fetchAssoc($result);
104  $this->setId($question_id);
105  $this->setObjId($data["obj_fi"]);
106  $this->setTitle($data["title"]);
107  $this->setComment($data["description"]);
108  $this->setNrOfTries($data['nr_of_tries']);
109  $this->setOriginalId($data["original_id"]);
110  $this->setAuthor($data["author"]);
111  $this->setPoints($data["points"]);
112  $this->setOwner($data["owner"]);
113  require_once './Services/RTE/classes/class.ilRTE.php';
114  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
115  $this->setMaxChars($data["maxnumofchars"]);
116  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
117 
118  try
119  {
120  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
121  }
123  {
124  }
125  }
126 
127  $result = $ilDB->queryF("SELECT * FROM qpl_num_range WHERE question_fi = %s ORDER BY aorder ASC",
128  array('integer'),
129  array($question_id)
130  );
131 
132  require_once './Modules/TestQuestionPool/classes/class.assNumericRange.php';
133  if ($result->numRows() > 0)
134  {
136  while ($data = $ilDB->fetchAssoc($result))
137  {
138  $this->setPoints($data['points']);
139  $this->setLowerLimit($data['lowerlimit']);
140  $this->setUpperLimit($data['upperlimit']);
141  }
142  }
143 
144  parent::loadFromDb($question_id);
145  }
146 
158  public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
159  {
160  if ($this->id <= 0)
161  {
162  // The question has not been saved. It cannot be duplicated
163  return;
164  }
165  // duplicate the question in database
166  $this_id = $this->getId();
167  $thisObjId = $this->getObjId();
168 
169  $clone = $this;
170  require_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
172  $clone->id = -1;
173 
174  if( (int)$testObjId > 0 )
175  {
176  $clone->setObjId($testObjId);
177  }
178 
179  if ($title)
180  {
181  $clone->setTitle($title);
182  }
183 
184  if ($author)
185  {
186  $clone->setAuthor($author);
187  }
188  if ($owner)
189  {
190  $clone->setOwner($owner);
191  }
192 
193  if ($for_test)
194  {
195  $clone->saveToDb($original_id);
196  }
197  else
198  {
199  $clone->saveToDb();
200  }
201 
202  // copy question page content
203  $clone->copyPageOfQuestion($this_id);
204  // copy XHTML media objects
205  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
206 
207  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
208 
209  return $clone->id;
210  }
211 
220  public function copyObject($target_questionpool_id, $title = "")
221  {
222  if ($this->id <= 0)
223  {
224  // The question has not been saved. It cannot be duplicated
225  return;
226  }
227  // duplicate the question in database
228  $clone = $this;
229  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
231  $clone->id = -1;
232  $source_questionpool_id = $this->getObjId();
233  $clone->setObjId($target_questionpool_id);
234  if ($title)
235  {
236  $clone->setTitle($title);
237  }
238  $clone->saveToDb();
239 
240  // copy question page content
241  $clone->copyPageOfQuestion($original_id);
242  // copy XHTML media objects
243  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
244 
245  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
246 
247  return $clone->id;
248  }
249 
250  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
251  {
252  if ($this->id <= 0)
253  {
254  // The question has not been saved. It cannot be duplicated
255  return;
256  }
257 
258  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
259 
260  $sourceQuestionId = $this->id;
261  $sourceParentId = $this->getObjId();
262 
263  // duplicate the question in database
264  $clone = $this;
265  $clone->id = -1;
266 
267  $clone->setObjId($targetParentId);
268 
269  if ($targetQuestionTitle)
270  {
271  $clone->setTitle($targetQuestionTitle);
272  }
273 
274  $clone->saveToDb();
275  // copy question page content
276  $clone->copyPageOfQuestion($sourceQuestionId);
277  // copy XHTML media objects
278  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
279 
280  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
281 
282  return $clone->id;
283  }
284 
285  public function getLowerLimit()
286  {
287  return $this->lower_limit;
288  }
289 
290  public function getUpperLimit()
291  {
292  return $this->upper_limit;
293  }
294 
295  public function setLowerLimit($a_limit)
296  {
297  $a_limit = str_replace(',', '.', $a_limit);
298  $this->lower_limit = $a_limit;
299  }
300 
301  public function setUpperLimit($a_limit)
302  {
303  $a_limit = str_replace(',', '.', $a_limit);
304  $this->upper_limit = $a_limit;
305  }
306 
312  public function getMaximumPoints()
313  {
314  return $this->getPoints();
315  }
316 
329  public function calculateReachedPoints($active_id, $pass = NULL, $returndetails = FALSE)
330  {
331  if( $returndetails )
332  {
333  throw new ilTestException('return details not implemented for '.__METHOD__);
334  }
335 
337  global $ilDB;
338 
339  $found_values = array();
340  if (is_null($pass))
341  {
342  $pass = $this->getSolutionMaxPass($active_id);
343  }
344  $result = $ilDB->queryF("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
345  array('integer','integer','integer'),
346  array($active_id, $this->getId(), $pass)
347  );
348  $data = $ilDB->fetchAssoc($result);
349 
350  $enteredvalue = $data["value1"];
351 
352  $points = 0;
353  if ($this->contains($enteredvalue))
354  {
355  $points = $this->getPoints();
356  }
357 
358  return $points;
359  }
360 
371  public function contains($value)
372  {
373  require_once './Services/Math/classes/class.EvalMath.php';
374  $eval = new EvalMath();
375  $eval->suppress_errors = TRUE;
376  $result = $eval->e($value);
377  if (($result === FALSE) || ($result === TRUE))
378  {
379  return FALSE;
380  }
381 
382  if (($result >= $eval->e($this->getLowerLimit())) && ($result <= $eval->e($this->getUpperLimit())))
383  {
384  return TRUE;
385  }
386  return FALSE;
387  }
388 
397  public function saveWorkingData($active_id, $pass = NULL)
398  {
400  global $ilDB;
401 
402  if (is_null($pass))
403  {
404  require_once './Modules/Test/classes/class.ilObjTest.php';
405  $pass = ilObjTest::_getPass($active_id);
406  }
407 
408  $entered_values = 0;
409  $numeric_result = str_replace(",",".",$_POST["numeric_result"]);
410 
411  require_once './Services/Math/classes/class.EvalMath.php';
412  $math = new EvalMath();
413  $math->suppress_errors = TRUE;
414  $result = $math->evaluate($numeric_result);
415  $returnvalue = true;
416  if ((($result === FALSE) || ($result === TRUE)) && (strlen($result) > 0))
417  {
418  ilUtil::sendInfo($this->lng->txt("err_no_numeric_value"), true);
419  $returnvalue = false;
420  }
421 
422  $this->getProcessLocker()->requestUserSolutionUpdateLock();
423 
424  $result = $ilDB->queryF("SELECT solution_id FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
425  array('integer','integer','integer'),
426  array($active_id, $this->getId(), $pass)
427  );
428 
429  $row = $ilDB->fetchAssoc($result);
430  $update = $row["solution_id"];
431  if ($update)
432  {
433  if (strlen($numeric_result))
434  {
435  $ilDB->update("tst_solutions", array(
436  "value1" => array("clob", trim($numeric_result)),
437  "tstamp" => array("integer", time())
438  ),
439  array(
440  "solution_id" => array("integer", $update)
441  )
442  );
443 
444  $entered_values++;
445  }
446  else
447  {
448  $ilDB->manipulateF("DELETE FROM tst_solutions WHERE solution_id = %s",
449  array('integer'),
450  array($update)
451  );
452  }
453  }
454  else
455  {
456  if (strlen($numeric_result))
457  {
458  $next_id = $ilDB->nextId('tst_solutions');
459  $ilDB->insert("tst_solutions", array(
460  "solution_id" => array("integer", $next_id),
461  "active_fi" => array("integer", $active_id),
462  "question_fi" => array("integer", $this->getId()),
463  "value1" => array("clob", trim($numeric_result)),
464  "value2" => array("clob", null),
465  "pass" => array("integer", $pass),
466  "tstamp" => array("integer", time())
467  )
468  );
469 
470  $entered_values++;
471  }
472  }
473 
474  $this->getProcessLocker()->releaseUserSolutionUpdateLock();
475 
476  if ($entered_values)
477  {
478  require_once './Modules/Test/classes/class.ilObjAssessmentFolder.php';
480  {
481  $this->logAction($this->lng->txtlng(
482  "assessment",
483  "log_user_entered_values",
485  ),
486  $active_id,
487  $this->getId()
488  );
489  }
490  }
491  else
492  {
493  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
495  {
496  $this->logAction($this->lng->txtlng(
497  "assessment",
498  "log_user_not_entered_values",
500  ),
501  $active_id,
502  $this->getId()
503  );
504  }
505  }
506 
507  return $returnvalue;
508  }
509 
510  public function saveAdditionalQuestionDataToDb()
511  {
513  global $ilDB;
514 
515  // save additional data
516  $ilDB->manipulateF( "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
517  array( "integer" ),
518  array( $this->getId() )
519  );
520 
521  $ilDB->manipulateF( "INSERT INTO " . $this->getAdditionalTableName(
522  ) . " (question_fi, maxnumofchars) VALUES (%s, %s)",
523  array( "integer", "integer" ),
524  array(
525  $this->getId(),
526  ($this->getMaxChars()) ? $this->getMaxChars() : 0
527  )
528  );
529  }
530 
531  public function saveAnswerSpecificDataToDb()
532  {
534  global $ilDB;
535 
536  // Write range to the database
537  $ilDB->manipulateF( "DELETE FROM qpl_num_range WHERE question_fi = %s",
538  array( 'integer' ),
539  array( $this->getId() )
540  );
541 
542  $next_id = $ilDB->nextId( 'qpl_num_range' );
543  $ilDB->manipulateF( "INSERT INTO qpl_num_range (range_id, question_fi, lowerlimit, upperlimit, points, aorder, tstamp)
544  VALUES (%s, %s, %s, %s, %s, %s, %s)",
545  array( 'integer', 'integer', 'text', 'text', 'float', 'integer', 'integer' ),
546  array( $next_id, $this->id, $this->getLowerLimit(), $this->getUpperLimit(
547  ), $this->getPoints(), 0, time() )
548  );
549  }
550 
558  protected function reworkWorkingData($active_id, $pass, $obligationsAnswered)
559  {
560  // nothing to rework!
561  }
562 
568  public function getQuestionType()
569  {
570  return "assNumeric";
571  }
572 
578  public function getMaxChars()
579  {
580  return $this->maxchars;
581  }
582 
588  public function setMaxChars($maxchars)
589  {
590  $this->maxchars = $maxchars;
591  }
592 
599  {
600  return "qpl_qst_numeric";
601  }
602 
608  {
610  }
611 
624  public function setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
625  {
626  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
627  $solutions = $this->getSolutionValues($active_id, $pass);
628  $worksheet->writeString($startrow, 0, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())), $format_title);
629  $worksheet->writeString($startrow, 1, ilExcelUtils::_convert_text($this->getTitle()), $format_title);
630  $i = 1;
631  $worksheet->writeString($startrow + $i, 0, ilExcelUtils::_convert_text($this->lng->txt("result")), $format_bold);
632  if (strlen($solutions[0]["value1"]))
633  {
634  $worksheet->write($startrow + $i, 1, ilExcelUtils::_convert_text($solutions[0]["value1"]));
635  }
636  $i++;
637  return $startrow + $i + 1;
638  }
639 }