ILIAS  release_7 Revision v7.30-3-g800a261c036
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
5include_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);
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());
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}
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81
An exception for terminatinating execution or to throw for unit testing.
static _lookupDBMode($a_obj_id)
static _getNotAttempted($a_obj_id)
Static function to read the number of user who have the status 'not_attempted'.
static _getCompleted($a_obj_id)
Static function to read the users who have the status 'completed'.
static _resetInfoCaches($a_obj_id)
static _getInProgress($a_obj_id)
Static function to read users who have the status 'in_progress'.
static _refreshStatus($a_obj_id, $a_users=null)
Set dirty.
static _getFailed($a_obj_id)
Static function to read the users who have the status 'completed'.
XML writer learning progress.
static _lookupSubType($a_obj_id)
lookup subtype id (scorm, )
static _enabledLearningProgress()
check wether learing progress is enabled or not
static userExists($a_usr_ids=array())
static _lookupName($a_user_id)
lookup user name
static getInstanceByRefId($a_ref_id, $stop_on_error=true)
get an instance of an Ilias object by reference id
Class ilObject Basic functions for all objects.
static _lookupObjId($a_id)
static _lookupType($a_id, $a_reference=false)
lookup object type
initAuth($sid)
Init authentication.
__raiseError($a_message, $a_code)
This class handles all DB changes necessary for fraunhofer.
deleteScorm2004Tracking($a_obj_id, $a_usr_ids)
Delete scorm 2004 tracking.
getLearningProgressChanges($sid, $timestamp, $include_ref_ids, $type_filter)
Get learning progress changes.
applyProgressFilter($obj_id, array $usr_ids, array $filter)
Apply progress filter.
deleteScormTracking($a_obj_id, $a_usr_ids)
Delete SCORM Tracking @global type $ilDB.
XML writer class.
xmlEndTag($tag)
Writes an endtag.
xmlElement($tag, $attrs=null, $data=null, $encode=true, $escape=true)
Writes a basic element (no children, just textual content)
xmlStartTag($tag, $attrs=null, $empty=false, $encode=true, $escape=true)
Writes a starttag.
global $DIC
Definition: goto.php:24
$query
$type
foreach($_POST as $key=> $value) $res
global $ilDB