ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilSoapLearningProgressAdministration.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
5 include_once './webservice/soap/classes/class.ilSoapAdministration.php';
6 
15 {
16  protected static $DELETE_PROGRESS_FILTER_TYPES = array('sahs', 'tst');
17 
23 
30 
31  protected static $PROGRESS_INFO_TYPES = array(
32  self::PROGRESS_FILTER_ALL,
33  self::PROGRESS_FILTER_IN_PROGRESS,
34  self::PROGRESS_FILTER_COMPLETED,
35  self::PROGRESS_FILTER_FAILED,
36  self::PROGRESS_FILTER_NOT_ATTEMPTED
37  );
38 
39 
40 
41  const USER_FILTER_ALL = -1;
42 
47  public function deleteProgress($sid, $ref_ids, $usr_ids, $type_filter, $progress_filter)
48  {
49  $this->initAuth($sid);
50  $this->initIlias();
51 
52  if (!is_array($usr_ids)) {
53  $usr_ids = (array) $usr_ids;
54  }
55  if (!is_array($type_filter)) {
56  $type_filter = (array) $type_filter;
57  }
58 
59  // Check session
60  if (!$this->__checkSession($sid)) {
61  return $this->__raiseError($this->__getMessage(), $this->__getMessageCode());
62  }
63 
64  // Check filter
65  if (array_diff((array) $type_filter, self::$DELETE_PROGRESS_FILTER_TYPES)) {
66  return $this->__raiseError('Invalid filter type given', 'Client');
67  }
68 
69  include_once 'Services/User/classes/class.ilObjUser.php';
70  if (!in_array(self::USER_FILTER_ALL, $usr_ids) and !ilObjUser::userExists($usr_ids)) {
71  return $this->__raiseError('Invalid user ids given', 'Client');
72  }
73 
74  $valid_refs = array();
75  foreach ((array) $ref_ids as $ref_id) {
76  $obj_id = ilObject::_lookupObjId($ref_id);
77  $type = ilObject::_lookupType($obj_id);
78 
79  // All containers
80  if ($GLOBALS['DIC']['objDefinition']->isContainer($type)) {
81  $all_sub_objs = array();
82  foreach (($type_filter) as $type_filter_item) {
83  $sub_objs = $GLOBALS['DIC']['tree']->getSubTree(
84  $GLOBALS['DIC']['tree']->getNodeData($ref_id),
85  false,
86  $type_filter_item
87  );
88  $all_sub_objs = array_merge($all_sub_objs, $sub_objs);
89  }
90 
91  foreach ($all_sub_objs as $child_ref) {
92  $child_type = ilObject::_lookupType(ilObject::_lookupObjId($child_ref));
93  if (!$GLOBALS['DIC']['ilAccess']->checkAccess('write', '', $child_ref)) {
94  return $this->__raiseError('Permission denied for : ' . $ref_id . ' -> type ' . $type, 'Client');
95  }
96  $valid_refs[] = $child_ref;
97  }
98  } elseif (in_array($type, $type_filter)) {
99  if (!$GLOBALS['DIC']['ilAccess']->checkAccess('write', '', $ref_id)) {
100  return $this->__raiseError('Permission denied for : ' . $ref_id . ' -> type ' . $type, 'Client');
101  }
102  $valid_refs[] = $ref_id;
103  } else {
104  return $this->__raiseError('Invalid object type given for : ' . $ref_id . ' -> type ' . $type, 'Client');
105  }
106  }
107 
108  // Delete tracking data
109  foreach ($valid_refs as $ref_id) {
110  include_once './Services/Object/classes/class.ilObjectFactory.php';
111  $obj = ilObjectFactory::getInstanceByRefId($ref_id, false);
112 
113  if (!$obj instanceof ilObject) {
114  return $this->__raiseError('Invalid reference id given : ' . $ref_id . ' -> type ' . $type, 'Client');
115  }
116 
117  // filter users
118  $valid_users = $this->applyProgressFilter($obj->getId(), (array) $usr_ids, (array) $progress_filter);
119 
120  switch ($obj->getType()) {
121  case 'sahs':
122  include_once './Modules/ScormAicc/classes/class.ilObjSAHSLearningModule.php';
123  $subtype = ilObjSAHSLearningModule::_lookupSubType($obj->getId());
124 
125  switch ($subtype) {
126  case 'scorm':
127  $this->deleteScormTracking($obj->getId(), (array) $valid_users);
128  break;
129 
130  case 'scorm2004':
131  $this->deleteScorm2004Tracking($obj->getId(), (array) $valid_users);
132  break;
133  }
134  break;
135 
136  case 'tst':
137 
139  $obj->removeTestResultsFromSoapLpAdministration(array_values((array) $valid_users));
140  break;
141  }
142 
143  // Refresh status
144  include_once './Services/Tracking/classes/class.ilLPStatusWrapper.php';
146  ilLPStatusWrapper::_refreshStatus($obj->getId(), $valid_users);
147  }
148  return true;
149  }
150 
157  public function getProgressInfo($sid, $a_ref_id, $a_progress_filter)
158  {
159  global $DIC;
160 
161  $this->initAuth($sid);
162  $this->initIlias();
163 
164  $ilAccess = $DIC->access();
165 
166  // Check session
167  if (!$this->__checkSession($sid)) {
168  return $this->__raiseError(
169  'Error ' . self::SOAP_LP_ERROR_AUTHENTICATION . ':' . $this->__getMessage(),
170  self::SOAP_LP_ERROR_AUTHENTICATION
171  );
172  }
173 
174  // Check filter
175  if (array_diff((array) $a_progress_filter, self::$PROGRESS_INFO_TYPES)) {
176  return $this->__raiseError(
177  'Error ' . self::SOAP_LP_ERROR_INVALID_FILTER . ': Invalid filter type given',
178  self::SOAP_LP_ERROR_INVALID_FILTER
179  );
180  }
181  // Check LP enabled
182  include_once("Services/Tracking/classes/class.ilObjUserTracking.php");
184  return $this->__raiseError(
185  'Error ' . self::SOAP_LP_ERROR_LP_NOT_ENABLED . ': Learning progress not enabled in ILIAS',
186  self::SOAP_LP_ERROR_LP_NOT_ENABLED
187  );
188  }
189 
190  include_once './Services/Object/classes/class.ilObjectFactory.php';
191  $obj = ilObjectFactory::getInstanceByRefId($a_ref_id, false);
192  if (!$obj instanceof ilObject) {
193  return $this->__raiseError(
194  'Error ' . self::SOAP_LP_ERROR_INVALID_REF_ID . ': Invalid reference id ' . $a_ref_id . ' given',
195  self::SOAP_LP_ERROR_INVALID_REF_ID
196  );
197  }
198 
199  // check lp available
200  include_once './Services/Tracking/classes/class.ilLPObjSettings.php';
201  $mode = ilLPObjSettings::_lookupDBMode($obj->getId());
202  if ($mode == ilLPObjSettings::LP_MODE_UNDEFINED) {
203  return $this->__raiseError(
204  'Error ' . self::SOAP_LP_ERROR_LP_NOT_AVAILABLE . ': Learning progress not available for objects of type ' .
205  $obj->getType(),
206  self::SOAP_LP_ERROR_LP_NOT_AVAILABLE
207  );
208  }
209 
210  // check rbac
214  if (!$ilAccess->checkRbacOrPositionPermissionAccess('read_learning_progress', 'read_learning_progress', $a_ref_id)) {
215  return $this->__raiseError(
216  'Error ' . self::SOAP_LP_ERROR_NO_PERMISSION . ': No Permission to access learning progress in this object',
217  self::SOAP_LP_ERROR_NO_PERMISSION
218  );
219  }
220 
221  include_once './Services/Xml/classes/class.ilXmlWriter.php';
222  $writer = new ilXmlWriter();
223  $writer->xmlStartTag(
224  'LearningProgressInfo',
225  array(
226  'ref_id' => $obj->getRefId(),
227  'type' => $obj->getType()
228  )
229  );
230 
231  $writer->xmlStartTag('LearningProgressSummary');
232 
233  include_once './Services/Tracking/classes/class.ilLPStatusWrapper.php';
234  if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_COMPLETED, $a_progress_filter)) {
235  $completed = ilLPStatusWrapper::_getCompleted($obj->getId());
236  $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
237  'read_learning_progress',
239  $a_ref_id,
240  $completed
241  );
242  $completed = count($completed);
243 
244  $writer->xmlElement(
245  'Status',
246  array(
247  'type' => self::PROGRESS_FILTER_COMPLETED,
248  'num' => (int) $completed
249  )
250  );
251  }
252  if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_IN_PROGRESS, $a_progress_filter)) {
253  $completed = ilLPStatusWrapper::_getInProgress($obj->getId());
254  $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
255  'read_learning_progress',
257  $a_ref_id,
258  $completed
259  );
260  $completed = count($completed);
261 
262  $writer->xmlElement(
263  'Status',
264  array(
265  'type' => self::PROGRESS_FILTER_IN_PROGRESS,
266  'num' => (int) $completed
267  )
268  );
269  }
270  if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_FAILED, $a_progress_filter)) {
271  $completed = ilLPStatusWrapper::_getFailed($obj->getId());
272  $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
273  'read_learning_progress',
275  $a_ref_id,
276  $completed
277  );
278  $completed = count($completed);
279 
280  $writer->xmlElement(
281  'Status',
282  array(
283  'type' => self::PROGRESS_FILTER_FAILED,
284  'num' => (int) $completed
285  )
286  );
287  }
288  if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_NOT_ATTEMPTED, $a_progress_filter)) {
289  $completed = ilLPStatusWrapper::_getNotAttempted($obj->getId());
290  $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
291  'read_learning_progress',
293  $a_ref_id,
294  $completed
295  );
296  $completed = count($completed);
297 
298  $writer->xmlElement(
299  'Status',
300  array(
301  'type' => self::PROGRESS_FILTER_NOT_ATTEMPTED,
302  'num' => (int) $completed
303  )
304  );
305  }
306  $writer->xmlEndTag('LearningProgressSummary');
307 
308 
309  $writer->xmlStartTag('UserProgress');
310  if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_COMPLETED, $a_progress_filter)) {
311  $completed = ilLPStatusWrapper::_getCompleted($obj->getId());
312  $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
313  'read_learning_progress',
315  $a_ref_id,
316  $completed
317  );
318 
319  $this->addUserProgress($writer, $completed, self::PROGRESS_FILTER_COMPLETED);
320  }
321  if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_IN_PROGRESS, $a_progress_filter)) {
322  $completed = ilLPStatusWrapper::_getInProgress($obj->getId());
323  $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
324  'read_learning_progress',
326  $a_ref_id,
327  $completed
328  );
329  $this->addUserProgress($writer, $completed, self::PROGRESS_FILTER_IN_PROGRESS);
330  }
331  if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_FAILED, $a_progress_filter)) {
332  $completed = ilLPStatusWrapper::_getFailed($obj->getId());
333  $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
334  'read_learning_progress',
336  $a_ref_id,
337  $completed
338  );
339  $this->addUserProgress($writer, $completed, self::PROGRESS_FILTER_FAILED);
340  }
341  if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_NOT_ATTEMPTED, $a_progress_filter)) {
342  $completed = ilLPStatusWrapper::_getNotAttempted($obj->getId());
343  $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
344  'read_learning_progress',
346  $a_ref_id,
347  $completed
348  );
349 
350  $this->addUserProgress($writer, $completed, self::PROGRESS_FILTER_NOT_ATTEMPTED);
351  }
352  $writer->xmlEndTag('UserProgress');
353  $writer->xmlEndTag('LearningProgressInfo');
354 
355  return $writer->xmlDumpMem();
356  }
357 
358  protected function addUserProgress(ilXmlWriter $writer, $users, $a_type)
359  {
360  foreach ($users as $user_id) {
361  $writer->xmlStartTag(
362  'User',
363  array(
364  'id' => $user_id,
365  'status' => $a_type
366  )
367  );
368 
369  $info = ilObjUser::_lookupName($user_id);
370  $writer->xmlElement('Login', array(), (string) $info['login']);
371  $writer->xmlElement('Firstname', array(), (string) $info['firstname']);
372  $writer->xmlElement('Lastname', array(), (string) $info['lastname']);
373  $writer->xmlEndTag('User');
374  }
375  }
376 
377 
386  protected function applyProgressFilter($obj_id, array $usr_ids, array $filter)
387  {
388  include_once './Services/Tracking/classes/class.ilLPStatusWrapper.php';
389 
390 
391  $all_users = array();
392  if (in_array(self::USER_FILTER_ALL, $usr_ids)) {
393  $all_users = array_unique(
394  array_merge(
398  )
399  );
400  } else {
401  $all_users = $usr_ids;
402  }
403 
404  if (!$filter or in_array(self::PROGRESS_FILTER_ALL, $filter)) {
405  $GLOBALS['DIC']['log']->write(__METHOD__ . ': Deleting all progress data');
406  return $all_users;
407  }
408 
409  $filter_users = array();
410  if (in_array(self::PROGRESS_FILTER_IN_PROGRESS, $filter)) {
411  $GLOBALS['DIC']['log']->write(__METHOD__ . ': Filtering in progress.');
412  $filter_users = array_merge($filter, ilLPStatusWrapper::_getInProgress($obj_id));
413  }
414  if (in_array(self::PROGRESS_FILTER_COMPLETED, $filter)) {
415  $GLOBALS['DIC']['log']->write(__METHOD__ . ': Filtering completed.');
416  $filter_users = array_merge($filter, ilLPStatusWrapper::_getCompleted($obj_id));
417  }
418  if (in_array(self::PROGRESS_FILTER_FAILED, $filter)) {
419  $GLOBALS['DIC']['log']->write(__METHOD__ . ': Filtering failed.');
420  $filter_users = array_merge($filter, ilLPStatusWrapper::_getFailed($obj_id));
421  }
422 
423  // Build intersection
424  return array_intersect($all_users, $filter_users);
425  }
426 
434  protected function deleteScormTracking($a_obj_id, $a_usr_ids)
435  {
436  global $DIC;
437 
438  $ilDB = $DIC['ilDB'];
439 
440  $query = 'DELETE FROM scorm_tracking ' .
441  'WHERE ' . $ilDB->in('user_id', $a_usr_ids, false, 'integer') . ' ' .
442  'AND obj_id = ' . $ilDB->quote($a_obj_id, 'integer') . ' ';
443  $res = $ilDB->manipulate($query);
444  return true;
445  }
446 
452  protected function deleteScorm2004Tracking($a_obj_id, $a_usr_ids)
453  {
454  global $DIC;
455 
456  $ilDB = $DIC['ilDB'];
457 
458  $query = 'SELECT cp_node_id FROM cp_node ' .
459  'WHERE nodename = ' . $ilDB->quote('item', 'text') . ' ' .
460  'AND cp_node.slm_id = ' . $ilDB->quote($a_obj_id, 'integer');
461  $res = $ilDB->query($query);
462 
463  $scos = array();
464  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
465  $scos[] = $row->cp_node_id;
466  }
467 
468  $query = 'DELETE FROM cmi_node ' .
469  'WHERE ' . $ilDB->in('user_id', (array) $a_usr_ids, false, 'integer') . ' ' .
470  'AND ' . $ilDB->in('cp_node_id', $scos, false, 'integer');
471  $ilDB->manipulate($query);
472  }
473 
477  public function getLearningProgressChanges($sid, $timestamp, $include_ref_ids, $type_filter)
478  {
479  $this->initAuth($sid);
480  $this->initIlias();
481 
482  if (!$this->__checkSession($sid)) {
483  return $this->__raiseError($this->__getMessage(), $this->__getMessageCode());
484  }
485  global $DIC;
486 
487  $rbacsystem = $DIC['rbacsystem'];
488  $tree = $DIC['tree'];
489  $ilLog = $DIC['ilLog'];
490 
491  // check administrator
492  $types = "";
493  if (is_array($type_filter)) {
494  $types = implode(",", $type_filter);
495  }
496 
497  // output lp changes as xml
498  try {
499  include_once './Services/Tracking/classes/class.ilLPXmlWriter.php';
500  $writer = new ilLPXmlWriter(true);
501  $writer->setTimestamp($timestamp);
502  $writer->setIncludeRefIds($include_ref_ids);
503  $writer->setTypeFilter($type_filter);
504  $writer->write();
505 
506  return $writer->xmlDumpMem(true);
507  } catch (UnexpectedValueException $e) {
508  return $this->__raiseError($e->getMessage(), 'Client');
509  }
510  }
511 }
static _lookupName($a_user_id)
lookup user name
static _getInProgress($a_obj_id)
Static function to read users who have the status &#39;in_progress&#39;.
xmlStartTag($tag, $attrs=null, $empty=false, $encode=true, $escape=true)
Writes a starttag.
applyProgressFilter($obj_id, array $usr_ids, array $filter)
Apply progress filter.
static _getCompleted($a_obj_id)
Static function to read the users who have the status &#39;completed&#39;.
This class handles all DB changes necessary for fraunhofer.
$type
global $DIC
Definition: saml.php:7
XML writer class.
static _refreshStatus($a_obj_id, $a_users=null)
Set dirty.
static userExists($a_usr_ids=array())
static _lookupSubType($a_obj_id)
lookup subtype id (scorm, )
static _resetInfoCaches($a_obj_id)
xmlEndTag($tag)
Writes an endtag.
static _getNotAttempted($a_obj_id)
Static function to read the number of user who have the status &#39;not_attempted&#39;.
static _getFailed($a_obj_id)
Static function to read the users who have the status &#39;completed&#39;.
$a_type
Definition: workflow.php:92
static _enabledLearningProgress()
check wether learing progress is enabled or not
XML writer learning progress.
static _lookupDBMode($a_obj_id)
foreach($_POST as $key=> $value) $res
static _lookupObjId($a_id)
__raiseError($a_message, $a_code)
$query
getLearningProgressChanges($sid, $timestamp, $include_ref_ids, $type_filter)
Get learning progress changes.
deleteScormTracking($a_obj_id, $a_usr_ids)
Delete SCORM Tracking type $ilDB.
static _lookupType($a_id, $a_reference=false)
lookup object type
$users
Definition: authpage.php:44
$row
xmlElement($tag, $attrs=null, $data=null, $encode=true, $escape=true)
Writes a basic element (no children, just textual content)
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81
deleteScorm2004Tracking($a_obj_id, $a_usr_ids)
Delete scorm 2004 tracking.
initAuth($sid)
Init authentication.
global $ilDB
static getInstanceByRefId($a_ref_id, $stop_on_error=true)
get an instance of an Ilias object by reference id
$info
Definition: index.php:5
$GLOBALS['JPEG_Segment_Names']
Global Variable: XMP_tag_captions.