ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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['objDefinition']->isContainer($type)) {
81 $all_sub_objs = array();
82 foreach (($type_filter) as $type_filter_item) {
83 $sub_objs = $GLOBALS['tree']->getSubTree(
84 $GLOBALS['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['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['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
151 public function getProgressInfo($sid, $a_ref_id, $a_progress_filter)
152 {
153 global $ilAccess;
154 $this->initAuth($sid);
155 $this->initIlias();
156
157 // Check session
158 if (!$this->__checkSession($sid)) {
159 return $this->__raiseError(
160 'Error ' . self::SOAP_LP_ERROR_AUTHENTICATION . ':' . $this->__getMessage(),
161 self::SOAP_LP_ERROR_AUTHENTICATION
162 );
163 }
164
165 // Check filter
166 if (array_diff((array) $a_progress_filter, self::$PROGRESS_INFO_TYPES)) {
167 return $this->__raiseError(
168 'Error ' . self::SOAP_LP_ERROR_INVALID_FILTER . ': Invalid filter type given',
169 self::SOAP_LP_ERROR_INVALID_FILTER
170 );
171 }
172 // Check LP enabled
173 include_once("Services/Tracking/classes/class.ilObjUserTracking.php");
175 return $this->__raiseError(
176 'Error ' . self::SOAP_LP_ERROR_LP_NOT_ENABLED . ': Learning progress not enabled in ILIAS',
177 self::SOAP_LP_ERROR_LP_NOT_ENABLED
178 );
179 }
180
181 include_once './Services/Object/classes/class.ilObjectFactory.php';
182 $obj = ilObjectFactory::getInstanceByRefId($a_ref_id, false);
183 if (!$obj instanceof ilObject) {
184 return $this->__raiseError(
185 'Error ' . self::SOAP_LP_ERROR_INVALID_REF_ID . ': Invalid reference id ' . $a_ref_id . ' given',
186 self::SOAP_LP_ERROR_INVALID_REF_ID
187 );
188 }
189
190 // check lp available
191 include_once './Services/Tracking/classes/class.ilLPObjSettings.php';
192 $mode = ilLPObjSettings::_lookupDBMode($obj->getId());
194 return $this->__raiseError(
195 'Error ' . self::SOAP_LP_ERROR_LP_NOT_AVAILABLE . ': Learning progress not available for objects of type ' .
196 $obj->getType(),
197 self::SOAP_LP_ERROR_LP_NOT_AVAILABLE
198 );
199 }
200
201 // check rbac
205 if (!$ilAccess->checkRbacOrPositionPermissionAccess('read_learning_progress', 'read_learning_progress', $a_ref_id)) {
206 return $this->__raiseError(
207 'Error ' . self::SOAP_LP_ERROR_NO_PERMISSION . ': No Permission to access learning progress in this object',
208 self::SOAP_LP_ERROR_NO_PERMISSION
209 );
210 }
211
212 include_once './Services/Xml/classes/class.ilXmlWriter.php';
213 $writer = new ilXmlWriter();
214 $writer->xmlStartTag(
215 'LearningProgressInfo',
216 array(
217 'ref_id' => $obj->getRefId(),
218 'type' => $obj->getType()
219 )
220 );
221
222 $writer->xmlStartTag('LearningProgressSummary');
223
224 include_once './Services/Tracking/classes/class.ilLPStatusWrapper.php';
225 if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_COMPLETED, $a_progress_filter)) {
226 $completed = ilLPStatusWrapper::_getCompleted($obj->getId());
227 $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
228 'read_learning_progress',
230 $a_ref_id,
231 $completed
232 );
233 $completed = count($completed);
234
235 $writer->xmlElement(
236 'Status',
237 array(
238 'type' => self::PROGRESS_FILTER_COMPLETED,
239 'num' => (int) $completed
240 )
241 );
242 }
243 if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_IN_PROGRESS, $a_progress_filter)) {
244 $completed = ilLPStatusWrapper::_getInProgress($obj->getId());
245 $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
246 'read_learning_progress',
248 $a_ref_id,
249 $completed
250 );
251 $completed = count($completed);
252
253 $writer->xmlElement(
254 'Status',
255 array(
256 'type' => self::PROGRESS_FILTER_IN_PROGRESS,
257 'num' => (int) $completed
258 )
259 );
260 }
261 if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_FAILED, $a_progress_filter)) {
262 $completed = ilLPStatusWrapper::_getFailed($obj->getId());
263 $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
264 'read_learning_progress',
266 $a_ref_id,
267 $completed
268 );
269 $completed = count($completed);
270
271 $writer->xmlElement(
272 'Status',
273 array(
274 'type' => self::PROGRESS_FILTER_FAILED,
275 'num' => (int) $completed
276 )
277 );
278 }
279 if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_NOT_ATTEMPTED, $a_progress_filter)) {
280 $completed = ilLPStatusWrapper::_getNotAttempted($obj->getId());
281 $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
282 'read_learning_progress',
284 $a_ref_id,
285 $completed
286 );
287 $completed = count($completed);
288
289 $writer->xmlElement(
290 'Status',
291 array(
292 'type' => self::PROGRESS_FILTER_NOT_ATTEMPTED,
293 'num' => (int) $completed
294 )
295 );
296 }
297 $writer->xmlEndTag('LearningProgressSummary');
298
299
300 $writer->xmlStartTag('UserProgress');
301 if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_COMPLETED, $a_progress_filter)) {
302 $completed = ilLPStatusWrapper::_getCompleted($obj->getId());
303 $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
304 'read_learning_progress',
306 $a_ref_id,
307 $completed
308 );
309
310 $this->addUserProgress($writer, $completed, self::PROGRESS_FILTER_COMPLETED);
311 }
312 if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_IN_PROGRESS, $a_progress_filter)) {
313 $completed = ilLPStatusWrapper::_getInProgress($obj->getId());
314 $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
315 'read_learning_progress',
317 $a_ref_id,
318 $completed
319 );
320 $this->addUserProgress($writer, $completed, self::PROGRESS_FILTER_IN_PROGRESS);
321 }
322 if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_FAILED, $a_progress_filter)) {
323 $completed = ilLPStatusWrapper::_getFailed($obj->getId());
324 $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
325 'read_learning_progress',
327 $a_ref_id,
328 $completed
329 );
330 $this->addUserProgress($writer, $completed, self::PROGRESS_FILTER_FAILED);
331 }
332 if (in_array(self::PROGRESS_FILTER_ALL, $a_progress_filter) or in_array(self::PROGRESS_FILTER_NOT_ATTEMPTED, $a_progress_filter)) {
333 $completed = ilLPStatusWrapper::_getNotAttempted($obj->getId());
334 $completed = $GLOBALS['DIC']->access()->filterUserIdsByRbacOrPositionOfCurrentUser(
335 'read_learning_progress',
337 $a_ref_id,
338 $completed
339 );
340
341 $this->addUserProgress($writer, $completed, self::PROGRESS_FILTER_NOT_ATTEMPTED);
342 }
343 $writer->xmlEndTag('UserProgress');
344 $writer->xmlEndTag('LearningProgressInfo');
345
346 return $writer->xmlDumpMem();
347 }
348
349 protected function addUserProgress(ilXmlWriter $writer, $users, $a_type)
350 {
351 foreach ($users as $user_id) {
352 $writer->xmlStartTag(
353 'User',
354 array(
355 'id' => $user_id,
356 'status' => $a_type
357 )
358 );
359
360 $info = ilObjUser::_lookupName($user_id);
361 $writer->xmlElement('Login', array(), (string) $info['login']);
362 $writer->xmlElement('Firstname', array(), (string) $info['firstname']);
363 $writer->xmlElement('Lastname', array(), (string) $info['lastname']);
364 $writer->xmlEndTag('User');
365 }
366 }
367
368
377 protected function applyProgressFilter($obj_id, array $usr_ids, array $filter)
378 {
379 include_once './Services/Tracking/classes/class.ilLPStatusWrapper.php';
380
381
382 $all_users = array();
383 if (in_array(self::USER_FILTER_ALL, $usr_ids)) {
384 $all_users = array_unique(
385 array_merge(
389 )
390 );
391 } else {
392 $all_users = $usr_ids;
393 }
394
395 if (!$filter or in_array(self::PROGRESS_FILTER_ALL, $filter)) {
396 $GLOBALS['log']->write(__METHOD__ . ': Deleting all progress data');
397 return $all_users;
398 }
399
400 $filter_users = array();
401 if (in_array(self::PROGRESS_FILTER_IN_PROGRESS, $filter)) {
402 $GLOBALS['log']->write(__METHOD__ . ': Filtering in progress.');
403 $filter_users = array_merge($filter, ilLPStatusWrapper::_getInProgress($obj_id));
404 }
405 if (in_array(self::PROGRESS_FILTER_COMPLETED, $filter)) {
406 $GLOBALS['log']->write(__METHOD__ . ': Filtering completed.');
407 $filter_users = array_merge($filter, ilLPStatusWrapper::_getCompleted($obj_id));
408 }
409 if (in_array(self::PROGRESS_FILTER_FAILED, $filter)) {
410 $GLOBALS['log']->write(__METHOD__ . ': Filtering failed.');
411 $filter_users = array_merge($filter, ilLPStatusWrapper::_getFailed($obj_id));
412 }
413
414 // Build intersection
415 return array_intersect($all_users, $filter_users);
416 }
417
425 protected function deleteScormTracking($a_obj_id, $a_usr_ids)
426 {
427 global $ilDB;
428
429 $query = 'DELETE FROM scorm_tracking ' .
430 'WHERE ' . $ilDB->in('user_id', $a_usr_ids, false, 'integer') . ' ' .
431 'AND obj_id = ' . $ilDB->quote($a_obj_id, 'integer') . ' ';
432 $res = $ilDB->manipulate($query);
433 return true;
434 }
435
441 protected function deleteScorm2004Tracking($a_obj_id, $a_usr_ids)
442 {
443 global $ilDB;
444
445 $query = 'SELECT cp_node_id FROM cp_node ' .
446 'WHERE nodename = ' . $ilDB->quote('item', 'text') . ' ' .
447 'AND cp_node.slm_id = ' . $ilDB->quote($a_obj_id, 'integer');
448 $res = $ilDB->query($query);
449
450 $scos = array();
451 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
452 $scos[] = $row->cp_node_id;
453 }
454
455 $query = 'DELETE FROM cmi_node ' .
456 'WHERE ' . $ilDB->in('user_id', (array) $a_usr_ids, false, 'integer') . ' ' .
457 'AND ' . $ilDB->in('cp_node_id', $scos, false, 'integer');
458 $ilDB->manipulate($query);
459 }
460
464 public function getLearningProgressChanges($sid, $timestamp, $include_ref_ids, $type_filter)
465 {
466 $this->initAuth($sid);
467 $this->initIlias();
468
469 if (!$this->__checkSession($sid)) {
470 return $this->__raiseError($this->__getMessage(), $this->__getMessageCode());
471 }
472 global $rbacsystem, $tree, $ilLog;
473
474 // check administrator
475 $types = "";
476 if (is_array($type_filter)) {
477 $types = implode($type_filter, ",");
478 }
479
480 // output lp changes as xml
481 try {
482 include_once './Services/Tracking/classes/class.ilLPXmlWriter.php';
483 $writer = new ilLPXmlWriter(true);
484 $writer->setTimestamp($timestamp);
485 $writer->setIncludeRefIds($include_ref_ids);
486 $writer->setTypeFilter($type_filter);
487 $writer->write();
488
489 return $writer->xmlDumpMem(true);
490 } catch (UnexpectedValueException $e) {
491 return $this->__raiseError($e->getMessage(), 'Client');
492 }
493 }
494}
$users
Definition: authpage.php:44
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.
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
$info
Definition: index.php:5
$query
$type
foreach($_POST as $key=> $value) $res
global $ilDB
$a_type
Definition: workflow.php:92