ILIAS  Release_4_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilSoapTestAdministration.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 
24 
33 include_once './webservice/soap/classes/class.ilSoapAdministration.php';
34 
36 {
38  {
40  }
41 
42  function isAllowedCall($sid, $active_id)
43  {
44  global $ilDB;
45 
46  $result = $ilDB->queryF("SELECT * FROM tst_times WHERE active_fi = %s ORDER BY started DESC",
47  array('integer'),
48  array($active_id)
49  );
50  if ($result->numRows())
51  {
52  $row = $ilDB->fetchAssoc($result);
53  if (preg_match("/(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2})/", $row["started"], $matches))
54  {
55  $time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
56  $now = time();
57  $diff = $now - $time;
58  $client = explode("::", $sid);
59  global $ilClientIniFile;
60  $expires = $ilClientIniFile->readVariable('session','expire');
61  if ($diff <= $expires)
62  {
63  return TRUE;
64  }
65  else
66  {
67  return FALSE;
68  }
69  }
70  else
71  {
72  return FALSE;
73  }
74  }
75  else
76  {
77  return FALSE;
78  }
79  }
80 
81  function saveQuestion($sid,$active_id,$question_id,$pass,$solution)
82  {
83  $this->initAuth($sid);
84  $this->initIlias();
85 
86  if(!$this->__checkSession($sid))
87  {
88  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
89  }
90  if (!$this->isAllowedCall($sid, $active_id))
91  {
92  return $this->__raiseError("The required user information is only available for active users.", "");
93  }
94 
95  if (is_array($solution) && (array_key_exists("item", $solution))) $solution = $solution["item"];
96 
97  $ilDB = $GLOBALS['ilDB'];
98  if (($active_id > 0) && ($question_id > 0) && (strlen($pass) > 0))
99  {
100  $affectedRows = $ilDB->manipulateF("DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
101  array('integer', 'integer', 'integer'),
102  array($active_id, $question_id, $pass)
103  );
104  }
105  $totalrows = 0;
106  for($i = 0; $i < count($solution); $i += 3)
107  {
108  $next_id = $ilDB->nextId('tst_solutions');
109  $affectedRows = $ilDB->insert("tst_solutions", array(
110  "solution_id" => array("integer", $next_id),
111  "active_fi" => array("integer", $active_id),
112  "question_fi" => array("integer", $question_id),
113  "value1" => array("clob", $solution[$i]),
114  "value2" => array("clob", $solution[$i+1]),
115  "points" => array("float", $solution[$i+2]),
116  "pass" => array("integer", $pass),
117  "tstamp" => array("integer", time())
118  ));
119  $totalrows += $affectedRows;
120  }
121  if ($totalrows == 0)
122  {
123  return $this->__raiseError("Wrong solution data. ILIAS did not execute any database queries: Solution data: " . print_r($solution, true));
124  }
125  else
126  {
127  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
128  $question = assQuestion::_instanciateQuestion($question_id);
129  $question->calculateResultsFromSolution($active_id, $pass);
130  }
131  return true;
132  }
133 
145  function saveQuestionSolution($sid,$active_id,$question_id,$pass,$solution)
146  {
147  $this->initAuth($sid);
148  $this->initIlias();
149 
150  if(!$this->__checkSession($sid))
151  {
152  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
153  }
154  if (!$this->isAllowedCall($sid, $active_id))
155  {
156  return $this->__raiseError("The required user information is only available for active users.", "");
157  }
158 
159  $solutions = array();
160  if (preg_match("/<values>(.*?)<\/values>/is", $solution, $matches))
161  {
162  if (preg_match_all("/<value>(.*?)<\/value><value>(.*?)<\/value><points>(.*?)<\/points>/is", $solution, $matches, PREG_SET_ORDER))
163  {
164  foreach ($matches as $match)
165  {
166  if (count($match) == 4)
167  {
168  for ($i = 1; $i < count($match); $i++)
169  {
170  array_push($solutions, trim($match[$i]));
171  }
172  }
173  }
174  }
175  }
176 
177  if (count($solutions) == 0)
178  {
179  return $this->__raiseError("Wrong solution data. ILIAS did not find one or more solution triplets: $solution", "");
180  }
181 
182  // Include main header
183  $ilDB = $GLOBALS['ilDB'];
184  if (($active_id > 0) && ($question_id > 0) && (strlen($pass) > 0))
185  {
186  $affectedRows = $ilDB->manipulateF("DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
187  array('integer', 'integer', 'integer'),
188  array($active_id, $question_id, $pass)
189  );
190  }
191  $totalrows = 0;
192  for($i = 0; $i < count($solutions); $i += 3)
193  {
194  $next_id = $ilDB->nextId('tst_solutions');
195  $affectedRows = $ilDB->insert("tst_solutions", array(
196  "solution_id" => array("integer", $next_id),
197  "active_fi" => array("integer", $active_id),
198  "question_fi" => array("integer", $question_id),
199  "value1" => array("clob", $solutions[$i]),
200  "value2" => array("clob", $solutions[$i+1]),
201  "points" => array("float", $solutions[$i+2]),
202  "pass" => array("integer", $pass),
203  "tstamp" => array("integer", time())
204  ));
205  $totalrows += $affectedRows;
206  }
207  if (count($totalrows) == 0)
208  {
209  return $this->__raiseError("Wrong solution data. ILIAS did not execute any database queries");
210  }
211  else
212  {
213  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
214  $question = assQuestion::_instanciateQuestion($question_id);
215  $question->calculateResultsFromSolution($active_id, $pass);
216  }
217  return "TRUE";
218  }
219 
230  function getQuestionSolution($sid,$active_id,$question_id,$pass)
231  {
232  $this->initAuth($sid);
233  $this->initIlias();
234 
235  if(!$this->__checkSession($sid))
236  {
237  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
238  }
239  if (!$this->isAllowedCall($sid, $active_id))
240  {
241  return $this->__raiseError("The required user information is only available for active users.", "");
242  }
243  $solution = array();
244  // Include main header
245  global $ilDB;
246 
247  $use_previous_answers = 1;
248 
249  $result = $ilDB->queryF("SELECT tst_tests.use_previous_answers FROM tst_tests, tst_active WHERE tst_tests.test_id = tst_active.test_fi AND tst_active.active_id = %s",
250  array('integer'),
251  array($active_id)
252  );
253  if ($result->numRows())
254  {
255  $row = $ilDB->fetchAssoc($result);
256  $use_previous_answers = $row["use_previous_answers"];
257  }
258  $lastpass = 0;
259  if ($use_previous_answers)
260  {
261  $result = $ilDB->queryF("SELECT MAX(pass) maxpass FROM tst_test_result WHERE active_fi = %s AND question_fi = %s",
262  array('integer', 'integer'),
263  array($active_id, $question_id)
264  );
265  if ($result->numRows() == 1)
266  {
267  $row = $ilDB->fetchAssoc($result);
268  $lastpass = $row["maxpass"];
269  }
270  }
271  else
272  {
273  $lastpass = $pass;
274  }
275 
276  if (($active_id > 0) && ($question_id > 0) && (strlen($lastpass) > 0))
277  {
278  $result = $ilDB->queryF("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
279  array('integer', 'integer', 'integer'),
280  array($active_id, $question_id, $lastpass)
281  );
282  if ($result->numRows())
283  {
284  while ($row = $ilDB->fetchAssoc($result))
285  {
286  array_push($solution, $row["value1"]);
287  array_push($solution, $row["value2"]);
288  array_push($solution, $row["points"]);
289  }
290  }
291  }
292  return $solution;
293  }
294 
303  function getTestUserData($sid, $active_id)
304  {
305  $this->initAuth($sid);
306  $this->initIlias();
307 
308  if(!$this->__checkSession($sid))
309  {
310  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
311  }
312  if (!$this->isAllowedCall($sid, $active_id))
313  {
314  return $this->__raiseError("The required user information is only available for active users.", "");
315  }
316 
317  global $lng, $ilDB;
318 
319  $result = $ilDB->queryF("SELECT user_fi, test_fi FROM tst_active WHERE active_id = %s",
320  array('integer'),
321  array($active_id)
322  );
323  $row = $ilDB->fetchAssoc($result);
324  $user_id = $row["user_fi"];
325  $test_id = $row["test_fi"];
326 
327  $result = $ilDB->queryF("SELECT anonymity FROM tst_tests WHERE test_id = %s",
328  array('integer'),
329  array($test_id)
330  );
331  $row = $ilDB->fetchAssoc($result);
332  $anonymity = $row["anonymity"];
333 
334  $result = $ilDB->queryF("SELECT firstname, lastname, title, login FROM usr_data WHERE usr_id = %s",
335  array('integer'),
336  array($user_id)
337  );
338 
339  $userdata = array();
340  if ($result->numRows() == 0)
341  {
342  $userdata["fullname"] = $lng->txt("deleted_user");
343  $userdata["title"] = "";
344  $userdata["firstname"] = "";
345  $userdata["lastname"] = $lng->txt("anonymous");
346  $userdata["login"] = "";
347  }
348  else
349  {
350  $data = $ilDB->fetchAssoc($result);
351  if (($user_id == ANONYMOUS_USER_ID) || ($anonymity))
352  {
353  $userdata["fullname"] = $lng->txt("anonymous");
354  $userdata["title"] = "";
355  $userdata["firstname"] = "";
356  $userdata["lastname"] = $lng->txt("anonymous");
357  $userdata["login"] = "";
358  }
359  else
360  {
361  $userdata["fullname"] = trim($data["title"] . " " . $data["firstname"] . " " . $data["lastname"]);
362  $userdata["title"] = $data["title"];
363  $userdata["firstname"] = $data["firstname"];
364  $userdata["lastname"] = $data["lastname"];
365  $userdata["login"] = $data["login"];
366  }
367  }
368  return array_values($userdata);
369  }
370 
381  function getPositionOfQuestion($sid, $active_id, $question_id, $pass)
382  {
383  $this->initAuth($sid);
384  $this->initIlias();
385 
386  if(!$this->__checkSession($sid))
387  {
388  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
389  }
390  if (!$this->isAllowedCall($sid, $active_id))
391  {
392  return $this->__raiseError("The required user information is only available for active users.", "");
393  }
394 
395  global $lng, $ilDB;
396 
397  $result = $ilDB->queryF("SELECT tst_tests.random_test FROM tst_active, tst_tests WHERE tst_active.active_id = %s AND tst_tests.test_id = tst_active.test_fi",
398  array('integer'),
399  array($active_id)
400  );
401  if ($result->numRows() != 1) return -1;
402  $row = $ilDB->fetchAssoc($result);
403  $is_random = $row["random_test"];
404 
405  include_once "./Modules/Test/classes/class.ilTestSequence.php";
406  $sequence = new ilTestSequence($active_id, $pass, $is_random);
407  return $sequence->getSequenceForQuestion($question_id);
408  }
409 
420  function getPreviousReachedPoints($sid, $active_id, $question_id, $pass)
421  {
422  $this->initAuth($sid);
423  $this->initIlias();
424 
425  if(!$this->__checkSession($sid))
426  {
427  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
428  }
429  if (!$this->isAllowedCall($sid, $active_id))
430  {
431  return $this->__raiseError("The required user information is only available for active users.", "");
432  }
433 
434  global $lng, $ilDB;
435 
436  $result = $ilDB->queryF("SELECT tst_tests.random_test FROM tst_active, tst_tests WHERE tst_active.active_id = %s AND tst_tests.test_id = tst_active.test_fi",
437  array('integer'),
438  array($active_id)
439  );
440  if ($result->numRows() != 1) return -1;
441  $row = $ilDB->fetchAssoc($result);
442  $is_random = $row["random_test"];
443 
444  include_once "./Modules/Test/classes/class.ilTestSequence.php";
445  $sequence = new ilTestSequence($active_id, $pass, $is_random);
446  $result = $ilDB->queryF("SELECT question_fi, points FROM tst_test_result WHERE active_fi = %s AND pass = %s",
447  array('integer', 'integer'),
448  array($active_id, $pass)
449  );
450  $reachedpoints = array();
451  while ($row = $ilDB->fetchAssoc($result))
452  {
453  $reachedpoints[$row["question_fi"]] = $row["points"];
454  }
455  $atposition = FALSE;
456  $pointsforposition = array();
457  foreach ($sequence->getUserSequence() as $seq)
458  {
459  if (!$atposition)
460  {
461  $qid = $sequence->getQuestionForSequence($seq);
462  if ($qid == $question_id)
463  {
464  $atposition = TRUE;
465  }
466  else
467  {
468  array_push($pointsforposition, $reachedpoints[$qid]);
469  }
470  }
471  }
472  return $pointsforposition;
473  }
474 
484  function getNrOfQuestionsInPass($sid, $active_id, $pass)
485  {
486  $this->initAuth($sid);
487  $this->initIlias();
488 
489  if(!$this->__checkSession($sid))
490  {
491  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
492  }
493  if (!$this->isAllowedCall($sid, $active_id))
494  {
495  return $this->__raiseError("The required user information is only available for active users.", "");
496  }
497 
498  global $lng, $ilDB;
499 
500  $result = $ilDB->queryF("SELECT tst_tests.random_test FROM tst_active, tst_tests WHERE tst_active.active_id = %s AND tst_tests.test_id = tst_active.test_fi",
501  array('integer'),
502  array($active_id)
503  );
504  if ($result->numRows() != 1) return 0;
505  $row = $ilDB->fetchAssoc($result);
506  $is_random = $row["random_test"];
507 
508  include_once "./Modules/Test/classes/class.ilTestSequence.php";
509  $sequence = new ilTestSequence($active_id, $pass, $is_random);
510  return $sequence->getUserQuestionCount();
511  }
512 
525  function getTestResults ($sid, $test_ref_id, $sum_only)
526  {
527  $this->initAuth($sid);
528  $this->initIlias();
529 
530  if(!$this->__checkSession($sid))
531  {
532  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
533  }
534  if(!strlen($test_ref_id))
535  {
536  return $this->__raiseError('No test id given. Aborting!',
537  'Client');
538  }
539  global $rbacsystem, $tree, $ilLog;
540 
541  if(ilObject::_isInTrash($test_ref_id))
542  {
543  return $this->__raiseError('Test is trashed. Aborting!',
544  'Client');
545  }
546 
547  // get obj_id
548  if(!$obj_id = ilObject::_lookupObjectId($test_ref_id))
549  {
550  return $this->__raiseError('No test found for id: '.$test_ref_id,
551  'Client');
552  }
553 
554 
555  // Check access
556  $permission_ok = false;
557  foreach($ref_ids = ilObject::_getAllReferences($obj_id) as $ref_id)
558  {
559  if($rbacsystem->checkAccess('write',$ref_id))
560  {
561  $permission_ok = true;
562  break;
563  }
564  }
565  if(!$permission_ok)
566  {
567  return $this->__raiseError('No permission to edit the object with id: '.$test_ref_id,
568  'Server');
569  }
570  // store into xml result set
571  include_once './webservice/soap/classes/class.ilXMLResultSet.php';
572  include_once './webservice/soap/classes/class.ilXMLResultSetWriter.php';
573 
574  $xmlResultSet = new ilXMLResultSet();
575  $xmlResultSet->addColumn("user_id");
576  $xmlResultSet->addColumn("login");
577  $xmlResultSet->addColumn("firstname");
578  $xmlResultSet->addColumn("lastname");
579  $xmlResultSet->addColumn("matriculation");
580 
581  include_once './Modules/Test/classes/class.ilObjTest.php';
582  $test_obj = new ilObjTest($obj_id, false);
583  $participants = $test_obj->getTestParticipants();
584 
585 
586  if ($sum_only)
587  {
588  $data = $test_obj->getAllTestResults($participants, false);
589  // create xml
590  $xmlResultSet->addColumn("maximum_points");
591  $xmlResultSet->addColumn("received_points");
592  // skip titles
593  $titles = array_shift($data);
594  foreach ($data as $row) {
595  $xmlRow = new ilXMLResultSetRow();
596  $xmlRow->setValue(0, $row["user_id"]);
597  $xmlRow->setValue(1, $row["login"]);
598  $xmlRow->setValue(2, $row["firstname"]);
599  $xmlRow->setValue(3, $row["lastname"]);
600  $xmlRow->setValue(4, $row["matriculation"]);
601  $xmlRow->setValue(5, $row["max_points"]);
602  $xmlRow->setValue(6, $row["reached_points"]);
603  $xmlResultSet->addRow($xmlRow);
604  }
605  } else {
606  $data = $test_obj->getDetailedTestResults($participants);
607  // create xml
608  $xmlResultSet->addColumn("question_id");
609  $xmlResultSet->addColumn("question_title");
610  $xmlResultSet->addColumn("maximum_points");
611  $xmlResultSet->addColumn("received_points");
612  foreach ($data as $row) {
613  $xmlRow = new ilXMLResultSetRow();
614  $xmlRow->setValue(0, $row["user_id"]);
615  $xmlRow->setValue(1, $row["login"]);
616  $xmlRow->setValue(2, $row["firstname"]);
617  $xmlRow->setValue(3, $row["lastname"]);
618  $xmlRow->setValue(4, $row["matriculation"]);
619  $xmlRow->setValue(5, $row["question_id"]);
620  $xmlRow->setValue(6, $row["question_title"]);
621  $xmlRow->setValue(7, $row["max_points"]);
622  $xmlRow->setValue(8, $row["reached_points"]);
623  $xmlResultSet->addRow($xmlRow);
624  }
625  }
626  // create writer
627  $xmlWriter = new ilXMLResultSetWriter($xmlResultSet);
628  $xmlWriter->start();
629  return $xmlWriter->getXML();
630  }
631 
632 
633 }
634 ?>