ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.ilSCORMOfflineMode.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2011 ILIAS open source, Extended GPL, see docs/LICENSE */
3//require_once "./Services/Object/classes/class.ilObject.php";
4
17{
18 public $type;
19 public $obj_id;
21 public $cmd_url;
25 public $som_url;
26
27 public $sop_dir;
28 public $som_dir;
30
31 public $sop_index;
33 public $lm_dir;
34 public $lm_index;
38 public $debug = false; // omit caching sop and som files for debugging
39
46 public function __construct()
47 {
48 global $ilias;
49 $this->ilias = $ilias;
50 $this->id = $_GET['ref_id'];
51 $this->obj_id = ilObject::_lookupObjectId($_GET['ref_id']);
52 include_once "./Modules/ScormAicc/classes/class.ilObjSAHSLearningModule.php";
53 $this->type = ilObjSAHSLearningModule::_lookupSubType($this->obj_id);
54 $this->cmd_url = './ilias.php?baseClass=ilSAHSPresentationGUI&cmd=';
55 $this->lm_cmd_url = './ilias.php?baseClass=ilSAHSPresentationGUI&ref_id=' . $this->id . '&cmd=';
56 $this->lm_info_url = $this->lm_cmd_url . 'infoScreen';
57 $this->player12_url = $this->cmd_url . 'offlineMode_player12';
58 $this->player2004_url = $this->cmd_url . 'offlineMode_player2004';
59 $this->som_url = $this->cmd_url . 'offlineMode_som';
60 $this->offlineMode = 'online';
61 $this->sop_index = './Modules/ScormAicc/sop/sop_index.html';
62 $this->sop_appcache = './Modules/ScormAicc/sop/sop.appcache';
63 $this->sop_dir = './Modules/ScormAicc/templates/sop/';
64 $this->som_dir = './Modules/ScormAicc/templates/som/';
65 $this->scripts_dir = './Modules/ScormAicc/scripts/';
66 $this->images_dir = './templates/default/images/scorm/';
67 $this->pouchdb_js = './libs/bower/bower_components/pouchdb/dist/pouchdb.min.js';
68 $this->jquery_js = './libs/bower/bower_components/jquery/dist/jquery.min.js';
69 $this->bootstrap_js = './libs/bower/bower_components/bootstrap/dist/js/bootstrap.min.js';
70 $this->bootstrap_css = './libs/bower/bower_components/bootstrap/dist/css/bootstrap.min.css';
71 $this->read();
72 }
73
74 public function getSopManifestEntries()
75 {
76 global $log;
77 $log->write("getSopManifestEntries ");
78 $manifest_string = "";
79 if (!$this->debug) {
80 // if ($this->type == "scorm2004") {
81 $BASE_DIR = './Modules/Scorm2004/';
82 $manifest_string .= ilUtil::getImagePath("scorm/asset.svg", false) . "\n";
83 $manifest_string .= ilUtil::getImagePath("scorm/completed.svg", false) . "\n";
84 $manifest_string .= ilUtil::getImagePath("scorm/not_attempted.svg", false) . "\n";
85 $manifest_string .= ilUtil::getImagePath("scorm/running.svg", false) . "\n";
86 $manifest_string .= ilUtil::getImagePath("scorm/incomplete.svg", false) . "\n";
87 $manifest_string .= ilUtil::getImagePath("scorm/passed.svg", false) . "\n";
88 $manifest_string .= ilUtil::getImagePath("scorm/failed.svg", false) . "\n";
89 // $manifest_string .= ilUtil::getImagePath("scorm/browsed.svg",false) . "\n";
90 $manifest_string .= ilUtil::getStyleSheetLocation() . "\n";
91 $manifest_string .= $BASE_DIR . 'templates/default/player.css' . "\n";
92 $manifest_string .= $BASE_DIR . 'scripts/buildrte/rte.js' . "\n";
93 $manifest_string .= $BASE_DIR . 'scripts/ilNestedList.js' . "\n";
94 $manifest_string .= iljQueryUtil::getLocaljQueryPath() . "\n";
95 $manifest_string .= $this->player2004_url . "\n";
96 // } else {
97 $manifest_string .= $this->player12_url . "\n";
98 // }
99 $manifest_string .= $this->som_url . "\n";
100 // $log->write("Manifest: ".$manifest_string);
101 $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->sop_dir));
102 foreach ($objects as $name => $object) {
103 if (preg_match('/\/\.+/', $name)) {
104 continue;
105 }
106 //$manifest_string .= preg_replace('/^\./','./Modules/ScormAicc',$name) . "\n"; // for cli
107 $manifest_string .= self::encodeuri($name) . "\n";
108 }
109 $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->som_dir));
110 foreach ($objects as $name => $object) {
111 if (preg_match('/\/\.+/', $name)) {
112 continue;
113 }
114 //$manifest_string .= preg_replace('/^\./','./Modules/ScormAicc',$name) . "\n"; // for cli
115 $manifest_string .= self::encodeuri($name) . "\n";
116 }
117
118 $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->scripts_dir));
119 foreach ($objects as $name => $object) {
120 if (preg_match('/\/\.+/', $name)) { //UK statt .+ .js und SCORM-Scripts weg
121 continue;
122 }
123 //$manifest_string .= preg_replace('/^\./','./Modules/ScormAicc',$name) . "\n"; // for cli
124 $manifest_string .= self::encodeuri($name) . "\n";
125 }
126 $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->images_dir));
127 foreach ($objects as $name => $object) {
128 if (preg_match('/\/\.+/', $name)) {
129 continue;
130 }
131 //$manifest_string .= preg_replace('/^\./','./Modules/ScormAicc',$name) . "\n"; // for cli
132 $manifest_string .= self::encodeuri($name) . "\n";
133 }
134
135 $manifest_string .= $this->pouchdb_js . "\n";
136 $manifest_string .= $this->jquery_js . "\n";
137 $manifest_string .= $this->bootstrap_js . "\n";
138 $manifest_string .= $this->bootstrap_css . "\n";
139 }
140 //$log->write($manifest_string);
141 return $manifest_string;
142 }
143
144 public function getLmManifestEntries()
145 { // ToDo: database support !!
146 global $log;
147 $log->write("getLmManifestEntries");
148 $this->lm_dir = ilUtil::getWebspaceDir("filesystem") . '/lm_data/lm_' . $this->obj_id;
149 $manifest_string = "";
150 $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->lm_dir));
151 foreach ($objects as $name => $object) {
152 if (preg_match('/\/\.+/', $name)) {
153 continue;
154 }
155 if (preg_match('/\.zip$/', $name)) {
156 continue;
157 }
158 //$manifest_string .= preg_replace('/^\./','./Modules/ScormAicc',$name) . "\n"; // for cli
159 $manifest_string .= self::encodeuri($name) . "\n";
160 }
161 //$log->write($manifest_string);
162 return $manifest_string;
163 }
164
165 // function il2sop() {
166 public function tracking2sop()
167 {
168 global $ilUser, $ilias;
169 // $this->setOfflineMode("il2sop");
170 header('Content-Type: text/javascript; charset=UTF-8');
171
172 include_once "./Modules/ScormAicc/classes/class.ilObjSAHSLearningModule.php";
173 $ob = new ilObjSAHSLearningModule($this->id);
174 $module_version = $ob->getModuleVersion();
175 $sahs_user = $this->il2sopSahsUser();
176 $support_mail = "";//TODO
177 $scorm_version = "1.2";
178 if ($this->type == "scorm2004") {
179 $scorm_version = "2004";
180 }
181 $tree="";
182
183 $learning_progress_enabled = 1;
184 include_once './Services/Object/classes/class.ilObjectLP.php';
185 $olp = ilObjectLP::getInstance($this->obj_id);
186 if ($olp->getCurrentMode() == 0) {
187 $learning_progress_enabled = 0;
188 }
189
190 $certificate_enabled = 0;
191
192 $adlact_data = null;
193 $ilias_version = $ilias->getSetting("ilias_version");
194
195 if ($this->type == 'scorm2004') {
196 include_once "./Modules/Scorm2004/classes/ilSCORM13Player.php";
197 $ob2004 = new ilSCORM13Player();
198 $init_data = json_encode($ob2004->getConfigForPlayer());
199 $resources = json_decode($ob2004->getCPDataInit());
200 $cmi = $ob2004->getCMIData($ilUser->getID(), $this->obj_id);
201 $max_attempt = $ob2004->get_max_attempts();
202 $adlact_data = json_decode($ob2004->getADLActDataInit());
203 //$globalobj_data = $ob2004->readGObjectiveInit();
204 } else {
205 include_once "./Modules/ScormAicc/classes/SCORM/class.ilObjSCORMInitData.php";
206 $slm_obj = new ilObjSCORMLearningModule($_GET["ref_id"]);
207 $init_data = ilObjSCORMInitData::getIliasScormVars($slm_obj);
208 $resources = json_decode(ilObjSCORMInitData::getIliasScormResources($this->obj_id));
209 $tree = json_decode(ilObjSCORMInitData::getIliasScormTree($this->obj_id));
210 $cmi = json_decode(ilObjSCORMInitData::getIliasScormData($this->obj_id));
211 $max_attempt = ilObjSCORMInitData::get_max_attempts($this->obj_id);
212 }
213 //UK max_attempt weg!
214 // if ($max_attempt == null) $max_attempt = 0;
215 $result = array(
216 'client_data' => array(
217 $support_mail
218 ),
219 'user_data' => $this->il2sopUserData(),
220 'lm' => array(
221 ilObject::_lookupTitle($this->obj_id),
222 ilObject::_lookupDescription($this->obj_id),
223 $scorm_version,
224 1,//active
225 $init_data,
226 $resources,
227 $tree,
228 $module_version,
229 "", //offline_zip_created!!!!!!!!
230 $learning_progress_enabled,
231 $certificate_enabled,
232 $max_attempt,
233 $adlact_data,
234 $ilias_version
235 ),
236 'sahs_user' => $sahs_user,
237 'cmi' => $cmi
238 );
239
240 print(json_encode($result));
241 }
242
243 public function getClientIdSop()
244 {
245 $iliasDomain = substr(ILIAS_HTTP_PATH, 7);
246 if (substr($iliasDomain, 0, 1) == "\/") {
247 $iliasDomain = substr($iliasDomain, 1);
248 }
249 if (substr($iliasDomain, 0, 4) == "www.") {
250 $iliasDomain = substr($iliasDomain, 4);
251 }
252 return $iliasDomain . ';' . CLIENT_ID;
253 }
254
255 public function il2sopUserData()
256 {
257 global $ilUser;
258 return array(
259 $ilUser->getLogin(),
260 "",
261 $ilUser->getFirstname(),
262 $ilUser->getLastname(),
263 $ilUser->getUTitle(),
264 $ilUser->getGender(),
265 $ilUser->getID()
266 );
267 }
268 public function il2sopSahsUser()
269 {
270 global $ilDB,$ilUser;
271 $package_attempts = 0;
272 $module_version = 1;//if module_version in sop is different...
273 $last_visited = "";
274 $first_access = null;
275 $last_access = null;
276 $last_status_change = null;
277 $total_time_sec = null;
278 $sco_total_time_sec = 0;
279 $status = 0;
280 $percentage_completed = 0;
281 $user_data = "";
282
283 global $ilDB,$ilUser;
284 $res = $ilDB->queryF(
285 'SELECT * FROM sahs_user WHERE obj_id=%s AND user_id=%s',
286 array('integer','integer'),
287 array($this->obj_id,$ilUser->getID())
288 );
289 while ($row = $ilDB->fetchAssoc($res)) {
290 $package_attempts = $row['package_attempts'];
291 $module_version = $row['module_version'];
292 $last_visited = $row['last_visited'];
293 if ($row['first_access'] != null) {
294 $first_access = strtotime($row['first_access'])*1000;//check Oracle!
295 }
296 if ($row['last_access'] != null) {
297 $last_access = strtotime($row['last_access'])*1000;//check Oracle!
298 }
299 $total_time_sec = $row['total_time_sec'];
300 $sco_total_time_sec = $row['sco_total_time_sec'];
301 $status = $row['status'];
302 $percentage_completed = $row['percentage_completed'];
303 }
304 if ($first_access == null) {
305 include_once './Services/Tracking/classes/class.ilChangeEvent.php';
306 $all = ilChangeEvent::_lookupReadEvents($this->obj_id, $ilUser->getID());
307 foreach ($all as $event) {
308 $first_access = strtotime($event['first_access'])*1000;//
309 }
310 }
311 return array($package_attempts, $module_version, $last_visited, $first_access, $last_access, $last_status_change, $total_time_sec, $sco_total_time_sec, $status, $percentage_completed, $user_data);
312 }
313
314 public function sop2il()
315 {
316 // sleep(5);
317 global $ilDB,$ilUser;
318 $in = file_get_contents("php://input");
319 $GLOBALS['ilLog']->write($in);
320 $ret = array('msg'=>array(),'err'=>array());
321
322 if (!$in || $in == "") {
323 $ret['err'][] = "no post data recieved";
324 print(json_encode($ret));
325 exit;
326 }
327 $userId=$ilUser->getID();
328 $result=true;
329
330 if ($this->type == 'scorm2004') {
331 $lm_set = $ilDB->queryF('SELECT default_lesson_mode, interactions, objectives, comments, time_from_lms FROM sahs_lm WHERE id = %s', array('integer'), array($this->obj_id));
332 while ($lm_rec = $ilDB->fetchAssoc($lm_set)) {
333 $defaultLessonMode=($lm_rec["default_lesson_mode"]);
334 $interactions=(ilUtil::yn2tf($lm_rec["interactions"]));
335 $objectives=(ilUtil::yn2tf($lm_rec["objectives"]));
336 $comments=(ilUtil::yn2tf($lm_rec["comments"]));
337 $time_from_lms=(ilUtil::yn2tf($lm_rec["time_from_lms"]));
338 }
339 include_once './Modules/Scorm2004/classes/class.ilSCORM2004StoreData.php';
340 $data = json_decode($in);
341 $GLOBALS['ilLog']->write('cmi_count=' . count($data->cmi));
342 for ($i=0; $i<count($data->cmi); $i++) {
343 if ($result==true) {
344 //$a_r=array();
345 $cdata=$data->cmi[$i];
347 $userId,
348 $this->obj_id,
349 $data->cmi[$i],//json_decode($data->cmi[$i]),
350 $comments,
351 $interactions,
352 $objectives
353 );
354 if (!is_array($a_r)) {
355 $result=false;
356 }
357 }
358 }
359 if ($result==true) {
360 $result=ilSCORM2004StoreData::syncGlobalStatus($userId, $this->obj_id, $data, $data->now_global_status, $time_from_lms);
361 }
362 } else {
363 include_once "./Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php";
364 $data = json_decode($in);
365 $result=ilObjSCORMTracking::storeJsApiCmi($userId, $this->obj_id, $data);
366 if ($result==true) {
367 $result=ilObjSCORMTracking::syncGlobalStatus($userId, $this->obj_id, $data, $data->now_global_status);
368 }
369 }
370 if ($result==true) {
371 $result=self::scormPlayerUnloadForSOP2il($data);
372 }
373
374 if ($result==false) {
375 $ret['err'][] = "invalid post data recieved";
376 } else {
377 $ret['msg'][] = "post data recieved";
378 }
379 header('Content-Type: text/plain; charset=UTF-8');
380 print json_encode($ret);
381 }
382
384 {
385 global $ilDB,$ilUser;
386 $first_access=null;
387 if ($data->first_access != null) {
388 $first_access=date('Y-m-d H:i:s', round($data->first_access/1000));
389 }
390 $last_access=null;
391 $i_last_access=null;
392 if ($data->last_access != null) {
393 $i_last_access = round($data->last_access/1000);
394 $last_access=date('Y-m-d H:i:s', $i_last_access);
395 include_once("./Services/Tracking/classes/class.ilChangeEvent.php");
396 ilChangeEvent::_updateAccessForScormOfflinePlayer($this->obj_id, $ilUser->getId(), $i_last_access, $first_access);
397 }
398 $last_status_change=null;
399 if ($data->last_status_change != null) {
400 $last_status_change=date('Y-m-d H:i:s', round($data->last_status_change/1000));
401 }
402 $GLOBALS['ilLog']->write('first_access=' . $first_access);
403 $res = $ilDB->queryF(
404 'UPDATE sahs_user SET first_access=%s, last_access=%s, last_status_change=%s, last_visited=%s, module_version=%s WHERE obj_id=%s AND user_id=%s',
405 array('timestamp','timestamp','timestamp','text','integer','integer','integer'),
406 array($first_access,$last_access,$last_status_change,$data->last_visited,$data->module_version, $this->obj_id,$ilUser->getId())
407 );
408
409 //populate last_status_change
410 return true;
411 }
412
413 //offlineMode: offline, online, il2sop, sop2il
414 public function setOfflineMode($a_mode)
415 {
416 global $ilDB,$ilUser;
417 $res = $ilDB->queryF(
418 'UPDATE sahs_user SET offline_mode=%s WHERE obj_id=%s AND user_id=%s',
419 array('text','integer','integer'),
420 array($a_mode, $this->obj_id,$ilUser->getId())
421 );
422 $this->offlineMode=$a_mode;
423 }
424 public function getOfflineMode()
425 {
426 return $this->offlineMode;
427 }
428
429 private function read()
430 {
431 global $ilDB,$ilUser;
432 $res = $ilDB->queryF(
433 'SELECT offline_mode FROM sahs_user WHERE obj_id=%s AND user_id=%s',
434 array('integer','integer'),
435 array($this->obj_id,$ilUser->getId())
436 );
437 while ($row = $ilDB->fetchAssoc($res)) {
438 if ($row['offline_mode'] != null && $row['offline_mode'] != '') {
439 $this->offlineMode = $row['offline_mode'];
440 } else {
441 $this->offlineMode = "online";
442 }
443 }
444 }
445
446 public static function checkIfAnyoneIsInOfflineMode($obj_id)
447 {
448 global $ilDB;
449 $res = $ilDB->queryF(
450 "SELECT count(*) cnt FROM sahs_user WHERE obj_id=%s AND offline_mode = 'offline'",
451 array('integer'),
452 array($obj_id)
453 );
454 $val_rec = $ilDB->fetchAssoc($res);
455 if ($val_rec["cnt"] == 0) {
456 return false;
457 }
458 return true;
459 }
460
461 public static function usersInOfflineMode($obj_id)
462 {
463 global $ilDB;
464 $users = array();
465 $res = $ilDB->queryF(
466 "SELECT user_id, lastname, firstname FROM sahs_user, usr_data "
467 . "WHERE sahs_user.obj_id=%s AND sahs_user.offline_mode = 'offline' AND sahs_user.user_id=usr_data.usr_id",
468 array('integer'),
469 array($obj_id)
470 );
471 while ($row = $ilDB->fetchAssoc($res)) {
472 $users[] = $row;
473 }
474 return $users;
475 }
476
477 public static function stopOfflineModeForUser($obj_id, $user_id)
478 {
479 global $ilDB;
480 $res = $ilDB->queryF(
481 "UPDATE sahs_user SET offline_mode='online' WHERE obj_id=%s AND user_id=%s",
482 array('integer','integer'),
483 array($obj_id,$user_id)
484 );
485 }
486
487 public static function encodeuri($path)
488 {
489 return implode('/', array_map('rawurlencode', explode('/', $path)));
490 }
491}
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
$result
if(php_sapi_name() !='cli') $in
Definition: Utf8Test.php:37
if(! $in) print
$users
Definition: authpage.php:44
$_GET["client_id"]
An exception for terminatinating execution or to throw for unit testing.
static _updateAccessForScormOfflinePlayer($obj_id, $usr_id, $i_last_access, $t_first_access)
_updateAccessForScormOfflinePlayer needed to synchronize last_access and first_access when learning m...
static _lookupReadEvents($obj_id, $usr_id=null)
Reads all read events which occured on the object which happened after the last time the user caught ...
Class ilObjSCORMLearningModule.
static _lookupSubType($a_obj_id)
lookup subtype id (scorm, )
static getIliasScormData($a_packageId)
static getIliasScormVars($slm_obj)
static get_max_attempts($a_packageId)
Get max.
static getIliasScormResources($a_packageId)
static getIliasScormTree($a_packageId)
Class ilObjSCORMLearningModule.
static syncGlobalStatus($userId, $packageId, $data, $new_global_status)
static storeJsApiCmi($user_id, $obj_id, $data)
static getInstance($a_obj_id)
static _lookupTitle($a_id)
lookup object title
static _lookupObjectId($a_ref_id)
lookup object id
static _lookupDescription($a_id)
lookup object description
static setCMIData($userId, $packageId, $data, $getComments, $getInteractions, $getObjectives)
static syncGlobalStatus($userId, $packageId, $data, $new_global_status, $time_from_lms)
Class ilSCORMOfflineMode.
static stopOfflineModeForUser($obj_id, $user_id)
static checkIfAnyoneIsInOfflineMode($obj_id)
static usersInOfflineMode($obj_id)
static getWebspaceDir($mode="filesystem")
get webspace directory
static getStyleSheetLocation($mode="output", $a_css_name="", $a_css_location="")
get full style sheet file name (path inclusive) of current user
static yn2tf($a_yn)
convert "y"/"n" to true/false
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static getLocaljQueryPath()
$i
Definition: disco.tpl.php:19
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
if($format !==null) $name
Definition: metadata.php:146
redirection script todo: (a better solution should control the processing via a xml file)
$ret
Definition: parser.php:6
foreach($_POST as $key=> $value) $res
global $ilDB
$lm_set
$ilUser
Definition: imgupload.php:18