1<?php 2 3/* Copyright (c) 1998-2011 ILIAS open source, Extended GPL, see docs/LICENSE */ 4 5include_once './Services/Tracking/classes/class.ilLPStatus.php'; 6 7/** 8 * @author Stefan Meyer <meyer@leifos.com> 9 * 10 * @version $Id$ 11 * 12 * @package ilias-tracking 13 * 14 */ 15class ilLPStatusSCORM extends ilLPStatus 16{ 17 public function __construct($a_obj_id) 18 { 19 global $DIC; 20 21 $ilDB = $DIC['ilDB']; 22 23 parent::__construct($a_obj_id); 24 $this->db = $ilDB; 25 } 26 27 28 public static function _getInProgress($a_obj_id) 29 { 30 $status_info = ilLPStatusWrapper::_getStatusInfo($a_obj_id); 31 $users = array(); 32 foreach ($status_info['in_progress'] as $in_progress) { 33 $users = array_merge($users, $in_progress); 34 } 35 $users = array_unique($users); 36 $users = array_diff($users, ilLPStatusWrapper::_getCompleted($a_obj_id)); 37 $users = array_diff($users, ilLPStatusWrapper::_getFailed($a_obj_id)); 38 39 return $users; 40 } 41 42 public static function _getCompleted($a_obj_id) 43 { 44 global $DIC; 45 46 $ilDB = $DIC['ilDB']; 47 48 include_once './Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php'; 49 50 $status_info = ilLPStatusWrapper::_getStatusInfo($a_obj_id); 51 52 $items = $status_info['scos']; 53 54 $counter = 0; 55 $users = array(); 56 foreach ($items as $sco_id) { 57 $tmp_users = $status_info['completed'][$sco_id]; 58 59 if (!$counter++) { 60 $users = $tmp_users; 61 } else { 62 $users = array_intersect($users, $tmp_users); 63 } 64 } 65 66 $users = array_diff($users, ilLPStatusWrapper::_getFailed($a_obj_id)); 67 return $users; 68 } 69 70 public static function _getFailed($a_obj_id) 71 { 72 $status_info = ilLPStatusWrapper::_getStatusInfo($a_obj_id); 73 74 if (!count($status_info['scos'])) { 75 return array(); 76 } 77 $users = array(); 78 foreach ($status_info['scos'] as $sco_id) { 79 /* #17913 - max attempts were removed in 5.1 80 // max attempts vs. failed 81 if(sizeof($status_info['in_progress'][$sco_id])) 82 { 83 foreach($status_info['in_progress'][$sco_id] as $user_id) 84 { 85 if(!in_array($user_id, $status_info['failed'][$sco_id])) 86 { 87 switch($status_info["subtype"]) 88 { 89 case 'hacp': 90 case 'aicc': 91 case 'scorm': 92 include_once './Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php'; 93 $has_max_attempts = ilObjSCORMTracking::_hasMaxAttempts($a_obj_id, $user_id); 94 break; 95 96 case 'scorm2004': 97 include_once("./Modules/Scorm2004/classes/class.ilSCORM2004Tracking.php"); 98 $has_max_attempts = ilSCORM2004Tracking::_hasMaxAttempts($a_obj_id, $user_id); 99 break; 100 } 101 102 if($has_max_attempts) 103 { 104 $status_info['failed'][$sco_id][] = $user_id; 105 } 106 } 107 } 108 } 109 */ 110 111 $users = array_merge($users, (array) $status_info['failed'][$sco_id]); 112 } 113 return array_unique($users); 114 } 115 116 public static function _getNotAttempted($a_obj_id) 117 { 118 $users = array(); 119 120 $members = ilObjectLP::getInstance($a_obj_id)->getMembers(); 121 if ($members) { 122 // diff in progress and completed (use stored result in LPStatusWrapper) 123 $users = array_diff((array) $members, ilLPStatusWrapper::_getInProgress($a_obj_id)); 124 $users = array_diff((array) $users, ilLPStatusWrapper::_getCompleted($a_obj_id)); 125 $users = array_diff((array) $users, ilLPStatusWrapper::_getFailed($a_obj_id)); 126 } 127 128 return $users; 129 } 130 131 132 public static function _getStatusInfo($a_obj_id) 133 { 134 // Which sco's determine the status 135 include_once './Services/Object/classes/class.ilObjectLP.php'; 136 $olp = ilObjectLP::getInstance($a_obj_id); 137 $collection = $olp->getCollectionInstance(); 138 if ($collection) { 139 $status_info['scos'] = $collection->getItems(); 140 } else { 141 $status_info['scos'] = array(); 142 } 143 $status_info['num_scos'] = count($status_info['scos']); 144 145 // Get subtype 146 include_once './Modules/ScormAicc/classes/class.ilObjSAHSLearningModule.php'; 147 $status_info['subtype'] = ilObjSAHSLearningModule::_lookupSubType($a_obj_id); 148 149 switch ($status_info['subtype']) { 150 case 'hacp': 151 case 'aicc': 152 include_once './Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php'; 153 $status_info['num_completed'] = ilObjSCORMTracking::_getCountCompletedPerUser($status_info['scos'], $a_obj_id); 154 155 include_once './Modules/ScormAicc/classes/class.ilObjAICCLearningModule.php'; 156 foreach (ilObjAICCLearningModule::_getTrackingItems($a_obj_id) as $item) { 157 if (in_array($item['obj_id'], $status_info['scos'])) { 158 $status_info['scos_title']["$item[obj_id]"] = $item['title']; 159 } 160 } 161 $info = ilObjSCORMTracking::_getProgressInfo($status_info['scos'], $a_obj_id); 162 break; 163 164 case 'scorm': 165 include_once './Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php'; 166 $status_info['num_completed'] = ilObjSCORMTracking::_getCountCompletedPerUser($status_info['scos'], $a_obj_id); 167 168 include_once './Modules/ScormAicc/classes/SCORM/class.ilSCORMItem.php'; 169 foreach ($status_info['scos'] as $sco_id) { 170 $status_info['scos_title'][$sco_id] = ilSCORMItem::_lookupTitle($sco_id); 171 } 172 $info = ilObjSCORMTracking::_getProgressInfo($status_info['scos'], $a_obj_id); 173 break; 174 175 case "scorm2004": 176 include_once './Modules/Scorm2004/classes/class.ilSCORM2004Tracking.php'; 177 $status_info['num_completed'] = ilSCORM2004Tracking::_getCountCompletedPerUser($status_info['scos'], $a_obj_id, true); 178 include_once './Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModule.php'; 179 foreach ($status_info['scos'] as $sco_id) { 180 $status_info['scos_title'][$sco_id] = ilObjSCORM2004LearningModule::_lookupItemTitle($sco_id); 181 } 182 183 $info = ilSCORM2004Tracking::_getItemProgressInfo($status_info['scos'], $a_obj_id, true); 184 break; 185 } 186 187 $status_info['completed'] = array(); 188 $status_info['failed'] = array(); 189 $status_info['in_progress'] = array(); 190 foreach ($status_info['scos'] as $sco_id) { 191 $status_info['completed'][$sco_id] = $info['completed'][$sco_id] ? $info['completed'][$sco_id] : array(); 192 $status_info['failed'][$sco_id] = $info['failed'][$sco_id] ? $info['failed'][$sco_id] : array(); 193 $status_info['in_progress'][$sco_id] = $info['in_progress'][$sco_id] ? $info['in_progress'][$sco_id] : array(); 194 } 195 //var_dump($status_info["completed"]); 196 return $status_info; 197 } 198 199 /** 200 * Determine status 201 * 202 * @param integer object id 203 * @param integer user id 204 * @param object object (optional depends on object type) 205 * @return integer status 206 */ 207 public function determineStatus($a_obj_id, $a_user_id, $a_obj = null) 208 { 209 global $DIC; 210 211 $ilObjDataCache = $DIC['ilObjDataCache']; 212 $ilDB = $DIC['ilDB']; 213 $ilLog = $DIC['ilLog']; 214 215 $status = self::LP_STATUS_NOT_ATTEMPTED_NUM; 216 217 // if the user has accessed the scorm object 218 // the status is at least "in progress" 219 include_once("./Services/Tracking/classes/class.ilChangeEvent.php"); 220 if (ilChangeEvent::hasAccessed($a_obj_id, $a_user_id)) { 221 $status = self::LP_STATUS_IN_PROGRESS_NUM; 222 } 223 //$ilLog->write("-".$status."-"); 224 225 // Which sco's determine the status 226 include_once './Services/Object/classes/class.ilObjectLP.php'; 227 $olp = ilObjectLP::getInstance($a_obj_id); 228 $collection = $olp->getCollectionInstance(); 229 if ($collection) { 230 $scos = $collection->getItems(); 231 if (sizeof($scos)) { // #15462 (#11513 - empty collections cannot be completed) 232 include_once './Modules/ScormAicc/classes/class.ilObjSAHSLearningModule.php'; 233 $subtype = ilObjSAHSLearningModule::_lookupSubType($a_obj_id); 234 switch ($subtype) { 235 case 'hacp': 236 case 'aicc': 237 case 'scorm': 238 include_once("./Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php"); 239 $scorm_status = ilObjSCORMTracking::_getCollectionStatus($scos, $a_obj_id, $a_user_id); 240 break; 241 242 case 'scorm2004': 243 include_once("./Modules/Scorm2004/classes/class.ilSCORM2004Tracking.php"); 244 $scorm_status = ilSCORM2004Tracking::_getCollectionStatus($scos, $a_obj_id, $a_user_id); 245 break; 246 } 247 248 switch ($scorm_status) { 249 case "in_progress": 250 $status = self::LP_STATUS_IN_PROGRESS_NUM; 251 break; 252 case "completed": 253 $status = self::LP_STATUS_COMPLETED_NUM; 254 break; 255 case "failed": 256 $status = self::LP_STATUS_FAILED_NUM; 257 break; 258 } 259 } 260 } 261 262 //$ilLog->write("-".$status."-"); 263 return $status; 264 } 265 266 /** 267 * Determine percentage 268 * 269 * @param integer object id 270 * @param integer user id 271 * @param object object (optional depends on object type) 272 * @return integer percentage 273 */ 274 public function determinePercentage($a_obj_id, $a_user_id, $a_obj = null) 275 { 276 // Which sco's determine the status 277 include_once './Services/Object/classes/class.ilObjectLP.php'; 278 $olp = ilObjectLP::getInstance($a_obj_id); 279 $collection = $olp->getCollectionInstance(); 280 if ($collection) { 281 $scos = $collection->getItems(); 282 $reqscos = count($scos); 283 284 include_once './Modules/ScormAicc/classes/class.ilObjSAHSLearningModule.php'; 285 $subtype = ilObjSAHSLearningModule::_lookupSubType($a_obj_id); 286 if ($subtype != "scorm2004") { 287 include_once("./Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php"); 288 $compl = ilObjSCORMTracking::_countCompleted($scos, $a_obj_id, $a_user_id); 289 } else { 290 include_once("./Modules/Scorm2004/classes/class.ilSCORM2004Tracking.php"); 291 $compl = ilSCORM2004Tracking::_countCompleted($scos, $a_obj_id, $a_user_id, true); 292 } 293 } 294 295 if ($reqscos > 0) { 296 $per = min(100, 100 / $reqscos * $compl); 297 } else { 298 $per = 100; 299 } 300 301 return $per; 302 } 303 304 public function refreshStatus($a_obj_id, $a_users = null) 305 { 306 parent::refreshStatus($a_obj_id, $a_users); 307 308 // this is restricted to SCOs in the current collection 309 include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php"); 310 $in_progress = ilLPStatusWrapper::_getInProgress($a_obj_id); 311 $completed = ilLPStatusWrapper::_getCompleted($a_obj_id); 312 $failed = ilLPStatusWrapper::_getFailed($a_obj_id); 313 $all_active_users = array_unique(array_merge($in_progress, $completed, $failed)); 314 315 // get all tracked users regardless of SCOs 316 include_once './Modules/ScormAicc/classes/class.ilObjSAHSLearningModule.php'; 317 $subtype = ilObjSAHSLearningModule::_lookupSubType($a_obj_id); 318 if ($subtype != "scorm2004") { 319 include_once("./Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php"); 320 $all_tracked_users = ilObjSCORMTracking::_getTrackedUsers($a_obj_id); 321 } else { 322 include_once("./Modules/Scorm2004/classes/class.ilSCORM2004Tracking.php"); 323 $all_tracked_users = ilSCORM2004Tracking::_getTrackedUsers($a_obj_id); 324 } 325 326 $not_attempted_users = array_diff($all_tracked_users, $all_active_users); 327 unset($all_tracked_users); 328 unset($all_active_users); 329 330 // reset all users which have no data for the current SCOs 331 if ($not_attempted_users) { 332 foreach ($not_attempted_users as $usr_id) { 333 // this will update any (parent) collections if necessary 334 ilLPStatus::writeStatus($a_obj_id, $usr_id, self::LP_STATUS_NOT_ATTEMPTED_NUM, 0); 335 } 336 } 337 } 338} 339