ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
ilSCORM13Player.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
5require_once("./Services/YUI/classes/class.ilYuiUtil.php");
6require_once("./Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModule.php");
7
14{
15
16 const ENABLE_GZIP = 0;
17
18 const NONE = 0;
19 const READONLY = 1;
20 const WRITEONLY = 2;
21 const READWRITE = 3;
22
23 static private $schema = array // order of entries matters!
24 (
25 'package' => array(
26 'user_id' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>user_id),
27 'learner_name' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>learner_name),
28 'slm_id' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>slm_id),
29 'mode' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>c_mode),
30 'credit' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>credit),
31 ),
32 'node' => array(
33 'accesscount' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>accesscount),
34 'accessduration' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>accessduration),
35 'accessed' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>accessed),
36 'activityAbsoluteDuration' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>activityabsduration),
37 'activityAttemptCount' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>activityattemptcount),
38 'activityExperiencedDuration' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>activityexpduration),
39 'activityProgressStatus' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>activityprogstatus),
40 'attemptAbsoluteDuration' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>attemptabsduration),
41 'attemptCompletionAmount' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>attemptcomplamount),
42 'attemptCompletionStatus' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>attemptcomplstatus),
43 'attemptExperiencedDuration' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>attemptexpduration),
44 'attemptProgressStatus' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>attemptprogstatus),
45 'audio_captioning' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>audio_captioning),
46 'audio_level' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>audio_level),
47 'availableChildren' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>availablechildren),
48 'cmi_node_id' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>cmi_node_id),
49 'completion' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>completion),
50 'completion_status' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>completion_status),
51 'completion_threshold' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>completion_threshold),
52 'cp_node_id' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>cp_node_id),
53 'created' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>created),
54 'credit' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>credit),
55 'delivery_speed' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>delivery_speed),
56 'entry' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>c_entry),
57 'exit' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>c_exit),
58 'language' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>c_language),
59 'launch_data' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>launch_data),
60 'learner_name' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>learner_name),
61 'location' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>location),
62 'max' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>c_max),
63 'min' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>c_min),
64 'mode' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>c_mode),
65 'modified' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>modified),
66 'progress_measure' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>progress_measure),
67 'raw' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>c_raw),
68 'scaled' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>scaled),
69 'scaled_passing_score' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>scaled_passing_score),
70 'session_time' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>session_time),
71 'success_status' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>success_status),
72 'suspend_data' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>suspend_data),
73 'total_time' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>total_time),
74 'user_id' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>user_id),
75 ),
76 'comment' => array (
77 'cmi_comment_id' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>cmi_comment_id),
78 'cmi_node_id' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>cmi_node_id),
79 'comment' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>c_comment),
80 'timestamp' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>c_timestamp),
81 'location' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>location),
82 'sourceIsLMS' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>sourceislms),
83 ),
84 'correct_response' => array(
85 'cmi_correct_response_id' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>cmi_correct_resp_id),
86 'cmi_interaction_id' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>cmi_interaction_id),
87 'pattern' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>pattern),
88 ),
89 'interaction' => array(
90 'cmi_interaction_id' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>cmi_interaction_id),
91 'cmi_node_id' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>cmi_node_id),
92 'description' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>description),
93 'id' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>id),
94 'latency' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>latency),
95 'learner_response' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>learner_response),
96 'result' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>result),
97 'timestamp' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>c_timestamp),
98 'type' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>c_type),
99 'weighting' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>weighting),
100 ),
101 'objective' => array(
102 'cmi_interaction_id' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>cmi_interaction_id),
103 'cmi_node_id' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>cmi_node_id),
104 'cmi_objective_id' => array('pattern'=>null, 'permission' => self::NONE, 'default'=>null, 'dbfield'=>cmi_objective_id),
105 'completion_status' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>completion_status),
106 'description' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>description),
107 'id' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>id),
108 'max' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>c_max),
109 'min' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>c_min),
110 'raw' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>c_raw),
111 'scaled' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>scaled),
112 'progress_measure' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>progress_measure),
113 'success_status' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>success_status),
114 'scope' => array('pattern'=>null, 'permission' => self::READWRITE, 'default'=>null, 'dbfield'=>scope),
115 ),
116 );
117
118 private $userId;
120 public $jsMode;
121
123 var $slm;
124 var $tpl;
125
126 function __construct()
127 {
128
129 global $ilias, $tpl, $ilCtrl, $ilUser, $lng;
130
131 //erase next?
132 if ($_REQUEST['learnerId']) {
133 $this->userId = $_REQUEST['learnerId'];
134 } else {
135 $this->userId = $GLOBALS['USER']['usr_id'];
136 }
137 $this->packageId = (int) $_REQUEST['packageId'];
138 $this->jsMode = strpos($_SERVER['HTTP_ACCEPT'], 'text/javascript')!==false;
139
140 $this->page = $_REQUEST['page'];
141
142 $this->slm =& new ilObjSCORM2004LearningModule($_GET["ref_id"], true);
143
144
145 $this->ilias =& $ilias;
146 $this->tpl =& $tpl;
147 $this->ctrl =& $ilCtrl;
148
149 $this->packageId=ilObject::_lookupObjectId($_GET['ref_id']);
150 $this->ref_id = $_GET['ref_id'];
151 $this->userId=$ilUser->getID();
152
153 if ($_GET['envEditor'] != null) {
154 $this->envEditor = $_GET['envEditor'];
155 } else {
156 $this->envEditor = 0;
157 }
158
159 }
160
164 function &executeCommand()
165 {
166 global $ilAccess, $ilLog, $ilUser, $lng, $ilias;
167
168 $next_class = $this->ctrl->getNextClass($this);
169 $cmd = $this->ctrl->getCmd();
170
171 if (!$ilAccess->checkAccess("read", "", $_GET["ref_id"]))
172 {
173 $ilias->raiseError($lng->txt("permission_denied"), $ilias->error_obj->WARNING);
174 }
175
176//$ilLog->write("SCORM2004 Player cmd: ".$cmd);
177
178 switch($cmd){
179
180 case 'getRTEjs':
181 $this->getRTEjs();
182 break;
183
184 case 'cp':
185 $this->getCPData();
186 break;
187
188 case 'adlact':
189 $this->getADLActData();
190 break;
191
192 case 'suspend':
193 $this->suspendADLActData();
194 break;
195
196 case 'getSuspend':
197 $this->getSuspendData();
198 break;
199
200 case 'gobjective':
201// $this->writeGObjective();
202 break;
203
204 case 'getGobjective':
205 $this->readGObjective();
206 break;
207
208 case 'getSharedData':
209 $this->readSharedData($_GET['node_id']);
210 break;
211
212 case 'setSharedData':
213 $this->writeSharedData($_GET['node_id']);
214 break;
215
216 case 'cmi':
217
218 if ($_SERVER['REQUEST_METHOD']=='POST') {
219 include_once './Modules/Scorm2004/classes/class.ilSCORM2004StoreData.php';
220 ilSCORM2004StoreData::persistCMIData($this->userId, $this->packageId,
221 $this->slm->getDefaultLessonMode(), $this->slm->getComments(),
222 $this->slm->getInteractions(), $this->slm->getObjectives(), $this->slm->getTime_from_lms());
223 //error_log("Saved CMI Data");
224 } else {
225 $this->fetchCMIData();
226 }
227 break;
228
229 case 'specialPage':
230 $this->specialPage();
231 break;
232
233 case 'debugGUI':
234 $this->debugGUI();
235 break;
236 case 'postLogEntry':
237 $this->postLogEntry();
238 break;
239 case 'liveLogContent':
240 $this->liveLogContent();
241 break;
242 case 'downloadLog':
243 $this->downloadLog();
244 break;
245 case 'openLog':
246 $this->openLog();
247 break;
248
249 case 'pingSession':
250 $this->pingSession();
251 break;
252 case 'scormPlayerUnload':
253 include_once './Modules/Scorm2004/classes/class.ilSCORM2004StoreData.php';
254 ilSCORM2004StoreData::scormPlayerUnload($this->userId, $this->packageId, $this->slm->getTime_from_lms());
255 break;
256
257 // case 'getConfigForPlayer':
258 // $this->getConfigForPlayer();
259 // break;
260 default:
261 $this->getPlayer();
262 break;
263 }
264
265 }
266
267 function getRTEjs()
268 {
269 $js_data = file_get_contents("./Modules/Scorm2004/scripts/buildrte/rte.js");
270 if (self::ENABLE_GZIP==1) {
271 ob_start("ob_gzhandler");
272 header('Content-Type: text/javascript; charset=UTF-8');
273 } else {
274 header('Content-Type: text/javascript; charset=UTF-8');
275 }
276 echo $js_data;
277 }
278
279
281 {
282 $webdir=str_replace("/ilias.php","",$_SERVER["SCRIPT_NAME"]);
283 //load ressources always with absolute URL..relative URLS fail on innersco navigation on certain browsers
284 $lm_dir=$webdir."/".ILIAS_WEB_DIR."/".$this->ilias->client_id ."/lm_data"."/lm_".$this->packageId;
285 return $lm_dir;
286 }
287
288 //config data also used for SOP
289 public function getConfigForPlayer()
290 {
292 $initSuspendData = null;
293 $cmi_learner_id = (string) $ilUser->getID();
294 $lm_set = new ilSetting("lm");
295 if($lm_set->get("scorm_login_as_learner_id") == 1) {
296 $cmi_learner_id = (string) $ilUser->getLogin();
297 }
298 $config = array
299 (
300 'scope'=>$this->getScope(),
301 'learner_id' => (string) $ilUser->getID(),
302 'cmi_learner_id' => $cmi_learner_id,
303 'course_id' => (string) $this->packageId,
304 'learner_name' => $ilUser->getFirstname()." ".$ilUser->getLastname(),
305 'mode' => $this->slm->getDefaultLessonMode(),
306 'credit' => $this->slm->getCreditMode(),
307 'auto_review' => $this->slm->getAutoReviewChar(),
308 'hide_navig' => $this->slm->getHideNavig(),
309 'hide_menu' => $this->slm->getNoMenu(),
310 'ie_force_render' => $this->slm->getIe_force_render(),
311 'fourth_edition' => $this->slm->getFourth_edition(),
312 'sequencing_enabled' => $this->slm->getSequencing(),
313 'interactions_storable' => $this->slm->getInteractions(),
314 'objectives_storable' => $this->slm->getObjectives(),
315 'comments_storable' => $this->slm->getComments(),
316 'time_from_lms' => $this->slm->getTime_from_lms(),
317 'auto_last_visited' => $this->slm->getAuto_last_visited(),
318 'lesson_mastery_score' => $this->slm->getMasteryScore(),
319 'checkSetValues' => $this->slm->getCheck_values(),
320 'auto_suspend' => $this->slm->getAutoSuspend(),
321 'suspend_data' => $initSuspendData,
322 'cp_data' => null,
323 'cmi_data' => null,
324 'adlact_data' => null,
325 'globalobj_data' => null
326 );
327 include_once './Modules/ScormAicc/classes/SCORM/class.ilObjSCORMInitData.php';
328 $config['status'] = ilObjSCORMInitData::getStatus($this->packageId, $ilUser->getID(), $this->slm->getAuto_last_visited(), "2004");
329 // $status['last_visited']=null;
330 // if($this->slm->getAuto_last_visited())
331 // {
332 // $status['last_visited']=$this->get_last_visited($this->packageId, $ilUser->getID());
333 // }
334 // $config['status'] = $status;
335
336 return $config;
337 }
338
339 public function getPlayer()
340 {
341 global $ilUser,$lng, $ilias, $ilSetting;
342
343 //WAC
344 require_once('./Services/WebAccessChecker/classes/class.ilWACSignedPath.php');
345 ilWACSignedPath::signFolderOfStartFile($this->getDataDirectory().'/imsmanifest.xml');
346
347 // player basic config data
348
349 $initSuspendData = null;
350 $initAdlactData = null;
351 if ($this->slm->getSequencing() == true) {
352 $initSuspendData = json_decode($this->getSuspendDataInit());
353 $initAdlactData = json_decode($this->getADLActDataInit());
354 $initGlobalobjData = $this->readGObjectiveInit();
355 }
356
357 $config = $this->getConfigForPlayer();
358
359 //session
360 if ($this->slm->getSession()) {
361// $session_timeout = (int)($ilias->ini->readVariable("session","expire"))/2;
362// $session_timeout = (int)ilSession::getIdleValue()/2;
363 $session_timeout = (int)ilWACSignedPath::getCookieMaxLifetimeInSeconds()-1;
364 } else {
365 $session_timeout = 0;
366 }
367 $config['session_ping'] = $session_timeout;
368
369 //url strings
370 $store_url = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=cmi&ref_id='.$_GET["ref_id"];
371 $unload_url = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=scormPlayerUnload&ref_id='.$_GET["ref_id"];
372 if ($this->slm->getSessionDeactivated()){
373 $store_url = 'storeScorm2004.php?package_id='.$this->packageId.'&ref_id='.$_GET["ref_id"].'&client_id='.$this->ilias->client_id.'&do=store';
374 $unload_url = 'storeScorm2004.php?package_id='.$this->packageId.'&ref_id='.$_GET["ref_id"].'&client_id='.$this->ilias->client_id.'&do=unload';
375 }
376 $config['cp_url'] = 'ilias.php?baseClass=ilSAHSPresentationGUI' . '&cmd=cp&ref_id='.$_GET["ref_id"];
377 $config['cmi_url'] = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=cmi&ref_id='.$_GET["ref_id"];
378 $config['store_url'] = $store_url;
379 $config['get_adldata_url'] = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=getSharedData&ref_id='.$_GET["ref_id"];
380 $config['set_adldata_url'] = 'ilias.php?baseClass=ilSAHSPresentationGUI' . '&cmd=setSharedData&ref_id=' . $_GET["ref_id"];
381 $config['adlact_url'] = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=adlact&ref_id='.$_GET["ref_id"];
382 $config['specialpage_url'] = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=specialPage&ref_id='.$_GET["ref_id"];
383 $config['suspend_url'] = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=suspend&ref_id='.$_GET["ref_id"];
384 $config['get_suspend_url'] = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=getSuspend&ref_id='.$_GET["ref_id"];
385 //next 2 lines could be deleted later
386 $config['gobjective_url'] = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=gobjective&ref_id='.$_GET["ref_id"];
387 $config['get_gobjective_url'] = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=getGobjective&ref_id='.$_GET["ref_id"];
388 $config['ping_url'] = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=pingSession&ref_id='.$_GET["ref_id"];
389 $config['scorm_player_unload_url']= $unload_url;
390 $config['post_log_url'] = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=postLogEntry&ref_id='.$_GET["ref_id"];
391 $config['livelog_url'] = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=liveLogContent&ref_id='.$_GET["ref_id"];
392 $config['package_url'] = $this->getDataDirectory()."/";
393
394 //editor
395 $config['envEditor'] = $this->envEditor;
396
397 //debug
398 $config['debug'] = $this->slm->getDebug();
399 $config['debug_fields'] = $this->getDebugValues();
400 $config['debug_fields_test'] = $this->getDebugValues(true);
401
402
403 //language strings
404 $langstrings['btnStart'] = $lng->txt('scplayer_start');
405 $langstrings['btnExit'] = $lng->txt('scplayer_exit');
406 $langstrings['btnExitAll'] = $lng->txt('scplayer_exitall');
407 $langstrings['btnSuspendAll'] = $lng->txt('scplayer_suspendall');
408 $langstrings['btnPrevious'] = $lng->txt('scplayer_previous');
409 $langstrings['btnContinue'] = $lng->txt('scplayer_continue');
410 $langstrings['btnhidetree']=$lng->txt('scplayer_hidetree');
411 $langstrings['btnshowtree']=$lng->txt('scplayer_showtree');
412 $langstrings['linkexpandTree']=$lng->txt('scplayer_expandtree');
413 $langstrings['linkcollapseTree']=$lng->txt('scplayer_collapsetree');
414 $langstrings['contCreditOff']=$lng->txt('cont_credit_off');
415 if ($this->slm->getAutoReviewChar() == "s") {
416 $langstrings['contCreditOff']=$lng->txt('cont_sc_score_was_higher_message');
417 }
418 $config['langstrings'] = $langstrings;
419
420 //template variables
421 //$this->tpl = new ilTemplate("tpl.scorm2004.player.html", false, false, "Modules/Scorm2004");
422 $this->tpl = new ilTemplate("tpl.scorm2004.player.html", true, true, "Modules/Scorm2004");
423
424 include_once("./Services/jQuery/classes/class.iljQueryUtil.php");
425 $this->tpl->setVariable("JS_FILE",iljQueryUtil::getLocaljQueryPath());
426
427 // include ilias rte css, if given
428 $rte_css = $this->slm->getDataDirectory()."/ilias_css_4_2/css/style.css";
429 if (is_file($rte_css))
430 {
431 $this->tpl->setCurrentBlock("rte_css");
432 $this->tpl->setVariable("RTE_CSS", $rte_css);
433 $this->tpl->parseCurrentBlock();
434 }
435
436
437 $this->tpl->setVariable('JSON_LANGSTRINGS', json_encode($langstrings));
438 // include_once("./Services/YUI/classes/class.ilYuiUtil.php");
439 // $this->tpl->setVariable('YUI_PATH', ilYuiUtil::getLocalPath());
440 // $this->tpl->setVariable('TREE_JS', "./Services/UIComponent/NestedList/js/ilNestedList.js");
441 $this->tpl->setVariable('TREE_JS', "./Modules/Scorm2004/scripts/ilNestedList.js");
442 $this->tpl->setVariable($langstrings);
443 $this->tpl->setVariable('DOC_TITLE', 'ILIAS SCORM 2004 Player');
444 if ($this->slm->getIe_compatibility()) $this->tpl->setVariable('IE_COMPATIBILITY', '<meta http-equiv="X-UA-Compatible" content="IE=7" />');
445 $this->tpl->setVariable("LOCATION_STYLESHEET", ilUtil::getStyleSheetLocation());
446 $this->tpl->setVariable('INIT_CP_DATA', json_encode(json_decode($this->getCPDataInit())));
447 $this->tpl->setVariable('INIT_CMI_DATA', json_encode($this->getCMIData($this->userId, $this->packageId)));
448 $this->tpl->setVariable('INIT_ADLACT_DATA', json_encode($initAdlactData));
449 $this->tpl->setVariable('INIT_GLOBALOBJ_DATA', json_encode($initGlobalobjData));
450 $this->tpl->setVariable('JS_DATA', json_encode($config));
451 list($tsfrac, $tsint) = explode(' ', microtime());
452 $this->tpl->setVariable('TIMESTAMP', sprintf('%d%03d', $tsint, 1000*(float)$tsfrac));
453 $this->tpl->setVariable('BASE_DIR', './Modules/Scorm2004/');
454 $this->tpl->setVariable('TXT_COLLAPSE',$lng->txt('scplayer_collapsetree'));
455 if ($this->slm->getDebug()) {
456 $this->tpl->setVariable('TXT_DEBUGGER',$lng->txt('scplayer_debugger'));
457 $this->tpl->setVariable('DEBUG_URL',"PopupCenter('ilias.php?baseClass=ilSAHSPresentationGUI&cmd=debugGUI&ref_id=".$_GET["ref_id"]."','Debug',800,600);");
458 } else {
459 $this->tpl->setVariable('TXT_DEBUGGER','');
460 $this->tpl->setVariable('DEBUG_URL','');
461 }
462
463 //set icons path
464 $this->tpl->setVariable('INLINE_CSS', ilSCORM13Player::getInlineCss());
465
466 //include scripts
467 if ($this->slm->getCacheDeactivated()){
468 $this->tpl->setVariable('JS_SCRIPTS', 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=getRTEjs&ref_id='.$_GET["ref_id"]);
469 } else {
470 $this->tpl->setVariable('JS_SCRIPTS', './Modules/Scorm2004/scripts/buildrte/rte-min.js');
471 }
472
473 //disable top menu
474 if ($this->slm->getNoMenu()=="y") {
475 $this->tpl->setVariable("VAL_DISPLAY", "style=\"display:none;\"");
476 } else {
477 $this->tpl->setVariable("VAL_DISPLAY", "");
478 }
479
480
481 //check for max_attempts and raise error if max_attempts is exceeded
482 if ($this->get_max_attempts()!=0) {
483 if ($this->get_actual_attempts() >= $this->get_max_attempts()) {
484 header('Content-Type: text/html; charset=utf-8');
485 echo($lng->txt("cont_sc_max_attempt_exceed"));
486 exit;
487 }
488 }
489
490 //count attempt
492 $this->resetSharedData();
493
494 $this->tpl->show("DEFAULT", false);
495 }
496
500 function getInlineCSS()
501 {
502 $is_tpl = new ilTemplate("tpl.scorm2004.inlinecss.html", true, true, "Modules/Scorm2004");
503 $is_tpl->setVariable('IC_ASSET', ilUtil::getImagePath("scorm/asset.svg",false));
504 $is_tpl->setVariable('IC_COMPLETED', ilUtil::getImagePath("scorm/completed.svg",false));
505 $is_tpl->setVariable('IC_NOTATTEMPTED', ilUtil::getImagePath("scorm/not_attempted.svg",false));
506 $is_tpl->setVariable('IC_RUNNING', ilUtil::getImagePath("scorm/running.svg",false));
507 $is_tpl->setVariable('IC_INCOMPLETE', ilUtil::getImagePath("scorm/incomplete.svg",false));
508 $is_tpl->setVariable('IC_PASSED', ilUtil::getImagePath("scorm/passed.svg",false));
509 $is_tpl->setVariable('IC_FAILED', ilUtil::getImagePath("scorm/failed.svg",false));
510 $is_tpl->setVariable('IC_BROWSED', ilUtil::getImagePath("scorm/browsed.svg",false));
511 return $is_tpl->get();
512 }
513
514 public function getCPData()
515 {
516 $jsdata = $this->getCPDataInit();
517 if ($this->jsMode)
518 {
519 header('Content-Type: text/javascript; charset=UTF-8');
520 print($jsdata);
521 }
522 else
523 {
524 header('Content-Type: text/plain; charset=UTF-8');
525 $jsdata = json_decode($jsdata);
526 print_r($jsdata);
527 }
528 }
529 function getCPDataInit()
530 {
531 global $ilDB;
532
533 $res = $ilDB->queryF(
534 'SELECT jsdata FROM cp_package WHERE obj_id = %s',
535 array('integer'),
536 array($this->packageId)
537 );
538 $packageData = $ilDB->fetchAssoc($res);
539
540 $jsdata = $packageData['jsdata'];
541 if (!$jsdata) $jsdata = 'null';
542
543 return $jsdata;
544 }
545
546
547 public function getADLActDataInit()
548 {
549 global $ilDB;
550
551 $res = $ilDB->queryF(
552 'SELECT activitytree FROM cp_package WHERE obj_id = %s',
553 array('integer'),
554 array($this->packageId)
555 );
556 $data = $ilDB->fetchAssoc($res);
557
558 $activitytree = $data['activitytree'];
559
560 if(!$activitytree)
561 {
562 $activitytree = 'null';
563 }
564 return $activitytree;
565 }
566
567 public function getADLActData()
568 {
569 $activitytree = $this->getADLActDataInit();
570 if($this->jsMode)
571 {
572 header('Content-Type: text/javascript; charset=UTF-8');
573 print($activitytree);
574 }
575 else
576 {
577 header('Content-Type: text/plain; charset=UTF-8');
578 $activitytree = json_decode($activitytree);
579 print_r($activitytree);
580 }
581 }
582
583 public function pingSession()
584 {
585 //WAC
586 require_once('./Services/WebAccessChecker/classes/class.ilWACSignedPath.php');
587 ilWACSignedPath::signFolderOfStartFile($this->getDataDirectory().'/imsmanifest.xml');
588 //do nothing except returning header
589 header('Content-Type: text/plain; charset=UTF-8');
590 print("");
591 }
592
593 public function getScope()
594 {
595 global $ilDB, $ilUser;
596
597 $res = $ilDB->queryF(
598 'SELECT global_to_system FROM cp_package WHERE obj_id = %s',
599 array('integer'),
600 array($this->packageId)
601 );
602 $data = $ilDB->fetchAssoc($res);
603
604 $gystem = $data['global_to_system'];
605 if($gystem == 1)
606 $gsystem = 'null';
607 else
608 $gsystem = $this->packageId;
609
610 return $gsystem;
611 }
612
613 public function getSuspendDataInit()
614 {
615 global $ilDB, $ilUser;
616
617 $res = $ilDB->queryF(
618 'SELECT data FROM cp_suspend WHERE obj_id = %s AND user_id = %s',
619 array('integer', 'integer'),
620 array($this->packageId, $ilUser->getId())
621 );
622 $data = $ilDB->fetchAssoc($res);
623
624 //delete delivered suspend data
625 $ilDB->manipulateF(
626 'DELETE FROM cp_suspend WHERE obj_id = %s AND user_id = %s',
627 array('integer', 'integer'),
628 array($this->packageId, $ilUser->getId())
629 );
630 return $data['data'];
631 }
632
633 public function getSuspendData()
634 {
635 $suspend_data = $this->getSuspendDataInit();
636 if($this->jsMode)
637 {
638 header('Content-Type: text/javascript; charset=UTF-8');
639 print($suspend_data);
640 }
641 else
642 {
643 header('Content-Type: text/plain; charset=UTF-8');
644 $suspend_data = json_decode($suspend_data);
645 print_r($suspend_data);
646 }
647 }
648
649 public function suspendADLActData()
650 {
651 global $ilDB, $ilUser;
652
653 $res = $ilDB->queryF(
654 'SELECT * FROM cp_suspend WHERE obj_id = %s AND user_id = %s',
655 array('integer', 'integer'),
656 array($this->packageId, $ilUser->getId())
657 );
658
659 if(!$ilDB->numRows($res))
660 {
661 $ilDB->insert('cp_suspend', array(
662 'data' => array('clob', file_get_contents('php://input')),
663 'obj_id' => array('integer', $this->packageId),
664 'user_id' => array('integer', $ilUser->getId())
665 ));
666 }
667 else
668 {
669 $ilDB->update('cp_suspend',
670 array(
671 'data' => array('clob', file_get_contents('php://input'))
672 ),
673 array(
674 'obj_id' => array('integer', $this->packageId),
675 'user_id' => array('integer', $ilUser->getId())
676 )
677 );
678 }
679 }
680
681 public function readGObjectiveInit()
682 {
683 global $ilDB, $ilUser;
684
685 //get json string
686 $g_data = new stdClass();
687
688 $global_to_system = 1;
689
690 $res = $ilDB->queryF('SELECT global_to_system FROM cp_package WHERE obj_id = %s',
691 array('integer'),
692 array($this->packageId)
693 );
694 while($data = $ilDB->fetchAssoc($res))
695 {
696 $global_to_system = $data['global_to_system'];
697 }
698
699 $query = 'SELECT objective_id, scope_id, satisfied, measure, user_id,
700 score_min, score_max, score_raw, completion_status,
701 progress_measure '
702 . 'FROM cmi_gobjective, cp_node, cp_mapinfo '
703 . 'WHERE (cmi_gobjective.objective_id <> %s AND cmi_gobjective.status IS NULL '
704 . 'AND cp_node.slm_id = %s AND cp_node.nodename = %s '
705 . 'AND cp_node.cp_node_id = cp_mapinfo.cp_node_id '
706 . 'AND cmi_gobjective.objective_id = cp_mapinfo.targetobjectiveid) '
707 . 'GROUP BY objective_id, scope_id, satisfied, measure, user_id,
708 score_min, score_max, score_raw, completion_status,
709 progress_measure';
710 $res = $ilDB->queryF(
711 $query,
712 array('text', 'integer', 'text'),
713 array('-course_overall_status-', $this->packageId, 'mapInfo')
714 );
715 while($row = $ilDB->fetchAssoc($res))
716 {
717 if (($global_to_system == 1 && $row['scope_id'] == 0) || ($global_to_system == 0 && $row['scope_id'] == $this->packageId)) {
718 $learner = $row['user_id'];
719 $objective_id = $row['objective_id'];
720 if($row['scope_id'] == 0)
721 {
722 $scope = "null";
723 }
724 else
725 {
726 $scope = $row['scope_id'];
727 }
728
729 if($row['satisfied'] != NULL)
730 {
731 $toset = $row['satisfied'];
732 $g_data->{"satisfied"}->{$objective_id}->{$learner}->{$scope} = $toset;
733 }
734
735 if($row['measure'] != NULL)
736 {
737 $toset = $row['measure'];
738 $g_data->{"measure"}->{$objective_id}->{$learner}->{$scope} = $toset;
739 }
740
741 if($row['score_raw'] != NULL)
742 {
743 $toset = $row['score_raw'];
744 $g_data->{"score_raw"}->{$objective_id}->{$learner}->{$scope} = $toset;
745 }
746
747 if($row['score_min'] != NULL)
748 {
749 $toset = $row['score_min'];
750 $g_data->{"score_min"}->{$objective_id}->{$learner}->{$scope} = $toset;
751 }
752
753 if($row['score_max'] != NULL)
754 {
755 $toset = $row['score_max'];
756 $g_data->{"score_max"}->{$objective_id}->{$learner}->{$scope} = $toset;
757 }
758
759 if($row['progress_measure'] != NULL)
760 {
761 $toset = $row['progress_measure'];
762 $g_data->{"progress_measure"}->{$objective_id}->{$learner}->{$scope} = $toset;
763 }
764
765 if($row['completion_status'] != NULL)
766 {
767 $toset = $row['completion_status'];
768 $g_data->{"completion_status"}->{$objective_id}->{$learner}->{$scope} = $toset;
769 }
770 }
771 }
772 return $g_data;
773 }
774
775 public function readGObjective()
776 {
777
778 $gobjective_data = json_encode($this->readGObjectiveInit());
779 if ($this->jsMode)
780 {
781 header('Content-Type: text/javascript; charset=UTF-8');
782 print($gobjective_data);
783 }
784 else
785 {
786 header('Content-Type: text/plain; charset=UTF-8');
787 $gobjective_data = json_decode($gobjective_data);
788 print_r($gobjective_data);
789 }
790 }
791
792
793 //Read the shared datascores for a given SCO
794 public function readSharedData($sco_node_id)
795 {
796
797 global $ilDB, $ilUser;
798 $dataStores = array( "data" => array(),
799 "permissions" => array());
800 $readPermissions = array();
801
802 $query = 'SELECT target_id, read_shared_data, write_shared_data '
803 . 'FROM cp_datamap '
804 . 'WHERE slm_id = %s '
805 . 'AND sco_node_id = %s '
806 . 'GROUP BY target_id, read_shared_data, write_shared_data';
807
808
809 $res = $ilDB->queryF(
810 $query,
811 array('integer', 'integer'),
812 array($this->packageId, $sco_node_id)
813 );
814
815 //Pass 1: Get all the shared data target_ids
816 // for this content package
817 while($row = $ilDB->fetchAssoc($res))
818 {
819 $storeVal = ($row['read_shared_data'] == 0 && $row['write_shared_data'] == 1 )
820 ? 'notWritten'
821 : null;
822
823 $dataStores["data"][$row['target_id']] = array( "store" => $storeVal,
824 "readSharedData" => $row['read_shared_data'],
825 "writeSharedData" => $row['write_shared_data']);
826 $dataStores["readPermissions"][$row['target_id']] = $row['read_shared_data'];
827 }
828
829 if(count($dataStores) < 1)
830 {
831 //If there are no datastores, then return nothing
832 echo "";
833 exit();
834 }
835 else if ($dataStores["readPermissions"] != null && array_sum($dataStores["readPermissions"]) != 0)
836 {
837
838 //If there exists at least one readSharedData permission, then
839 //fill in the existing values (if any) already in the store.
840
841 //Create the params to add to the Pass 2 query (get existing values)
842 $params = array("types" => array("integer", "integer"),
843 "values" => array($this->userId, $this->packageId));
844
845 $paramTemplate = '';
846
847 //See if readSharedData is set for each datamap.
848 //If set to true, then add it to the search query
849 foreach($dataStores["data"] as $key => $val)
850 {
851 if($dataStores["readPermissions"][$key] == 1
852 && $dataStores["data"][$key]["store"] != 'notWritten')
853 {
854 $params["types"][] = "text";
855 $params["values"][] = $key;
856 $paramTemplate .= '%s, ';
857 }
858 }
859
860 //Get rid of the trailing ', '
861 $paramTemplate = substr($paramTemplate, 0, strlen($paramTemplate) - 2);
862
863 //Pass 2: Query for values previously saved by the user
864 $query = 'SELECT target_id, store '
865 . 'FROM adl_shared_data '
866 . 'WHERE user_id = %s '
867 . 'AND slm_id = %s '
868 . 'AND target_id IN (' . $paramTemplate . ')';
869
870
871 $res = $ilDB->queryF(
872 $query,
873 $params["types"],
874 $params["values"]
875 );
876
877 while($row = $ilDB->fetchAssoc($res))
878 {
879 $dataStores["data"][$row['target_id']]["store"] = $row['store'];
880 }
881 }
882
883 header('Content-Type: text/javascript; charset=UTF-8');
884
885 echo json_encode($dataStores["data"]);
886 }
887
888 public function writeSharedData($sco_node_id)
889 {
890 global $ilDB, $ilUser;
891 $g_data = json_decode(file_get_contents('php://input'));
892
893 //Step 1: Get the writeable stores for this SCO that already have values
894 $query = 'SELECT dm.target_id, sd.store '
895 . 'FROM cp_datamap dm '
896 . 'LEFT JOIN adl_shared_data sd '
897 . 'ON(dm.slm_id = sd.slm_id AND dm.target_id = sd.target_id) '
898 . 'WHERE sco_node_id = %s '
899 . 'AND dm.slm_id = %s '
900 . 'AND write_shared_data = 1 '
901 . 'AND user_id = %s';
902
903 $res = $ilDB->QueryF(
904 $query,
905 array('integer', 'integer', 'integer'),
906 array($sco_node_id, $this->packageId, $this->userId)
907 );
908
909 $dataStores = array();
910 $originalVals = array();
911 while($row = $ilDB->fetchAssoc($res))
912 {
913 $id = $row['target_id'];
914 $dataStores[$id] = $g_data->{$id};
915 $originalVals[$id] = $row['store'];
916 }
917
918
919 //Step 2: Add the writeable stores
920 foreach($g_data as $key => $obj)
921 {
922 //If it's already created in adl_shared_data, we
923 //need to update it.
924 if(array_key_exists($key, $dataStores) )
925 {
926 if($obj == 'notWritten') continue;
927
928 $query = 'UPDATE adl_shared_data '
929 . 'SET store = %s '
930 . 'WHERE user_id = %s '
931 . 'AND target_id = %s '
932 . 'AND slm_id = %s ';
933
934 $ilDB->manipulateF(
935 $query,
936 array('text', 'integer', 'text', 'integer'),
937 array($dataStores[$key], $this->userId, $key, $this->packageId)
938 );
939 } else
940 {
941 //Check for writability
942 $res = $ilDB->queryF(
943 'SELECT write_shared_data, cp_node_id '
944 . 'FROM cp_datamap '
945 . 'WHERE target_id = %s '
946 . 'AND slm_id = %s '
947 . 'AND sco_node_id = %s',
948 array('text', 'integer', 'integer'),
949 array($key, $this->packageId, $sco_node_id));
950
951 $row = $ilDB->fetchAssoc($res);
952 if($row["write_shared_data"] != 1)
953 {
954 continue;
955 }
956
957 //If it's writeable, then add the new value into the database
958 $res = $ilDB->manipulateF(
959 'INSERT INTO adl_shared_data (slm_id, user_id, target_id, store, cp_node_id) VALUES (%s, %s, %s, %s, %s)',
960 array('integer', 'integer', 'text', 'text', 'integer'),
961 array($this->packageId, $this->userId, $key, $obj, $row["cp_node_id"]));
962 }
963 }
964 echo "1";
965 exit();
966
967 }
968
969 public function specialPage() {
970
971 global $lng;
972
973 $specialpages = array (
974 "_COURSECOMPLETE_" => "seq_coursecomplete",
975 "_ENDSESSION_" => "seq_endsession",
976 "_SEQBLOCKED_" => "seq_blocked",
977 "_NOTHING_" => "seq_nothing",
978 "_ERROR_" => "seq_error",
979 "_DEADLOCK_" => "seq_deadlock",
980 "_INVALIDNAVREQ_" => "seq_invalidnavreq",
981 "_SEQABANDON_" => "seq_abandon",
982 "_SEQABANDONALL_" => "seq_abandonall",
983 "_TOC_" => "seq_toc"
984 );
985
986 $this->tpl = new ilTemplate("tpl.scorm2004.specialpages.html", false, false, "Modules/Scorm2004");
987 $this->tpl->setVariable("LOCATION_STYLESHEET", ilUtil::getStyleSheetLocation());
988 $this->tpl->setVariable('TXT_SPECIALPAGE',$lng->txt($specialpages[$this->page]));
989 if ($this->page!="_TOC_" && $this->page!="_SEQABANDON_" && $this->page!="_SEQABANDONALL_" ) {
990 $this->tpl->setVariable('CLOSE_WINDOW',$lng->txt('seq_close'));
991 } else {
992 $this->tpl->setVariable('CLOSE_WINDOW',"");
993 }
994 $this->tpl->show("DEFAULT", false);
995 }
996
997
998 public function fetchCMIData()
999 {
1000 $data = $this->getCMIData($this->userId, $this->packageId);
1001 if ($this->jsMode)
1002 {
1003 header('Content-Type: text/javascript; charset=UTF-8');
1004 print(json_encode($data));
1005 }
1006 else
1007 {
1008 header('Content-Type: text/plain; charset=UTF-8');
1009 print(var_export($data, true));
1010 }
1011 }
1012
1013
1018 private function normalizeFields($table, &$node)
1019 {
1020 return;
1021 foreach (self::$schema[$table] as $k => $v)
1022 {
1023 $value = $node->$k;
1024 if (isset($value) && is_string($v) && !preg_match($v, $value))
1025 {
1026 unset($node->$k);
1027 }
1028 }
1029 }
1030
1031 public function getCMIData($userId, $packageId)
1032 {
1033 global $ilDB;
1034
1035 $i_check=0;
1036 $result = array(
1037 'schema' => array(),
1038 'data' => array()
1039 );
1040
1041 foreach(self::$schema as $k => &$v)
1042 {
1043 $result['schema'][$k] = array_keys($v);
1044 $q = '';
1045 switch ($k)
1046 {
1047 case "node":
1048 $q = 'SELECT cmi_node.*
1049 FROM cmi_node
1050 INNER JOIN cp_node ON cmi_node.cp_node_id = cp_node.cp_node_id
1051 WHERE cmi_node.user_id = %s
1052 AND cp_node.slm_id = %s';
1053
1054 break;
1055
1056 case "comment":
1057 if ($i_check>7) {
1058 $i_check-=8;
1059 if ($this->slm->getComments()) $q = 'SELECT
1060 cmi_comment.cmi_comment_id,
1061 cmi_comment.cmi_node_id,
1062 cmi_comment.c_comment,
1063 cmi_comment.c_timestamp,
1064 cmi_comment.location,
1065 cmi_comment.sourceislms
1066 FROM cmi_comment
1067 INNER JOIN cmi_node ON cmi_node.cmi_node_id = cmi_comment.cmi_node_id
1068 INNER JOIN cp_node ON cp_node.cp_node_id = cmi_node.cp_node_id
1069 WHERE cmi_node.user_id = %s
1070 AND cp_node.slm_id = %s
1071 ORDER BY cmi_comment.cmi_comment_id';
1072 }
1073
1074 break;
1075
1076 case "correct_response":
1077 if ($i_check>3) {
1078 $i_check-=4;
1079 if ($this->slm->getInteractions()) $q = 'SELECT cmi_correct_response.*
1080 FROM cmi_correct_response
1081 INNER JOIN cmi_interaction
1082 ON cmi_interaction.cmi_interaction_id = cmi_correct_response.cmi_interaction_id
1083 INNER JOIN cmi_node ON cmi_node.cmi_node_id = cmi_interaction.cmi_node_id
1084 INNER JOIN cp_node ON cp_node.cp_node_id = cmi_node.cp_node_id
1085 WHERE cmi_node.user_id = %s
1086 AND cp_node.slm_id = %s
1087 ORDER BY cmi_correct_response.cmi_correct_resp_id';
1088 }
1089 break;
1090
1091 case "interaction":
1092 if ($i_check>1) {
1093 $i_check-=2;
1094 if ($this->slm->getInteractions()) $q = 'SELECT
1095 cmi_interaction.cmi_interaction_id,
1096 cmi_interaction.cmi_node_id,
1097 cmi_interaction.description,
1098 cmi_interaction.id,
1099 cmi_interaction.latency,
1100 cmi_interaction.learner_response,
1101 cmi_interaction.result,
1102 cmi_interaction.c_timestamp,
1103 cmi_interaction.c_type,
1104 cmi_interaction.weighting
1105 FROM cmi_interaction
1106 INNER JOIN cmi_node ON cmi_node.cmi_node_id = cmi_interaction.cmi_node_id
1107 INNER JOIN cp_node ON cp_node.cp_node_id = cmi_node.cp_node_id
1108 WHERE cmi_node.user_id = %s
1109 AND cp_node.slm_id = %s
1110 ORDER BY cmi_interaction.cmi_interaction_id';
1111 }
1112 break;
1113
1114 case "objective":
1115 if ($i_check>0) {
1116 if ($this->slm->getObjectives()) $q = 'SELECT
1117 cmi_objective.cmi_interaction_id,
1118 cmi_objective.cmi_node_id,
1119 cmi_objective.cmi_objective_id,
1120 cmi_objective.completion_status,
1121 cmi_objective.description,
1122 cmi_objective.id,
1123 cmi_objective.c_max,
1124 cmi_objective.c_min,
1125 cmi_objective.c_raw,
1126 cmi_objective.scaled,
1127 cmi_objective.progress_measure,
1128 cmi_objective.success_status,
1129 cmi_objective.scope
1130 FROM cmi_objective
1131 INNER JOIN cmi_node ON cmi_node.cmi_node_id = cmi_objective.cmi_node_id
1132 INNER JOIN cp_node ON cp_node.cp_node_id = cmi_node.cp_node_id
1133 WHERE cmi_node.user_id = %s
1134 AND cp_node.slm_id = %s
1135 ORDER BY cmi_objective.cmi_objective_id';
1136 }
1137 break;
1138
1139 case "package"://delete because data exist except of learner_name
1140 $q = 'SELECT usr_data.usr_id user_id,
1141 CONCAT(CONCAT(COALESCE(usr_data.firstname, \'\'), \' \'), COALESCE(usr_data.lastname, \'\')) learner_name,
1142 sahs_lm.id slm_id , sahs_lm.default_lesson_mode "mode", sahs_lm.credit
1143 FROM usr_data, cp_package
1144 INNER JOIN sahs_lm ON cp_package.obj_id = sahs_lm.id
1145 WHERE usr_data.usr_id = %s
1146 AND sahs_lm.id = %s';
1147
1148 break;
1149
1150 }
1151
1152 $result['data'][$k] = array();
1153 if ($q != '') {
1154 $types = array('integer', 'integer');
1155 $values = array($userId, $packageId);
1156 $res = $ilDB->queryF($q, $types, $values);
1157
1158 while($row = $ilDB->fetchAssoc($res))
1159 {
1160 $tmp_result = array();
1161 foreach($row as $key => $value)
1162 {
1163 if ($k == "comment" && $key == "c_timestamp" && strpos($value,' ')==10) $value = str_replace(' ','T',$value);
1164 $tmp_result[] = $value;
1165 if($k=="node" && $key=="additional_tables" && $i_check<$value){
1166 $i_check=$value;
1167// $GLOBALS['ilLog']->write($i_check);
1168 }
1169 }
1170 $result['data'][$k][] = $tmp_result;
1171 }
1172 }
1173 }
1174 return $result;
1175 }
1176
1177
1178 function quoteJSONArray($a_array)
1179 {
1180 global $ilDB;
1181
1182 if(!is_array($a_array) or !count($a_array))
1183 {
1184 return array("''");
1185 }
1186
1187 foreach($a_array as $k => $item)
1188 {
1189 if ($item != null) {
1190 $a_array[$k] = $ilDB->quote($item);
1191 } else {
1192 $a_array[$k] = "NULL";
1193 }
1194 }
1195
1196 return $a_array;
1197 }
1198
1206 public function getMimetype($filename)
1207 {
1208 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1210 }
1211
1217 public function getCookie()
1218 {
1219 return unserialize(base64_decode($_COOKIE[IL_OP_COOKIE_NAME]));
1220 }
1221
1222 public function setCookie($cook)
1223 {
1224 setCookie(IL_OP_COOKIE_NAME, base64_encode(serialize($cook)));
1225 }
1226
1233 public function readFile($path)
1234 {
1235 if (headers_sent())
1236 {
1237 die('Error: Cookie could not be established');
1238 }
1239
1240 $SAHS_LM_POSITION = 1; // index position of sahs_lm id in splitted path_info
1241
1242 $comp = explode('/', (string) $path);
1243 $sahs = $comp[$SAHS_LM_POSITION];
1244 $cook = $this->getCookie();
1245 $perm = $cook[$sahs];
1246
1247 if (!$perm)
1248 {
1249 // check login an package access
1250 // TODO add rbac check function here
1251 $perm = 1;
1252 if (!$perm)
1253 {
1254 header('HTTP/1.0 401 Unauthorized');
1255 die('/* Unauthorized */');
1256 }
1257 // write cookie
1258 $cook[$sahs] = $perm;
1259 $this->setCookie($cook);
1260 }
1261
1262 $path = '.' . $path;
1263 if (!is_file($path))
1264 {
1265 header('HTTP/1.0 404 Not Found');
1266 die('/* Not Found ' . $path . '*/');
1267 }
1268
1269 // send mimetype to client
1270 header('Content-Type: ' . $this->getMimetype($path));
1271
1272 // let page be cached in browser for session duration
1273 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + session_cache_expire()*60) . ' GMT');
1274 header('Cache-Control: private');
1275
1276 // now show it to the user and be fine
1277 readfile($path);
1278 die();
1279 }
1280
1285 {
1286 include_once "./Modules/ScormAicc/classes/SCORM/class.ilObjSCORMInitData.php";
1287 return ilObjSCORMInitData::get_max_attempts($this->packageId);
1288 }
1289
1291 {
1292 global $ilDB;
1293
1294 $res = $ilDB->queryF(
1295 'SELECT module_version FROM sahs_lm WHERE id = %s',
1296 array('integer'),
1297 array($this->packageId));
1298 $row = $ilDB->fetchAssoc($res);
1299
1300 return $row['module_version'];
1301 }
1302
1307 {
1308 global $ilDB, $ilUser;
1309 $val_set = $ilDB->queryF('SELECT package_attempts FROM sahs_user WHERE obj_id = %s AND user_id = %s',
1310 array('integer','integer'), array($this->packageId,$this->userId));
1311 $val_rec = $ilDB->fetchAssoc($val_set);
1312 $attempts = $val_rec["package_attempts"];
1313 if ($attempts == null) $attempts = 0;
1314 return $attempts;
1315 }
1316
1321 {
1322 global $ilDB, $ilUser;
1323 $res = $ilDB->queryF(
1324 'SELECT package_attempts,count(*) cnt FROM sahs_user WHERE obj_id = %s AND user_id = %s GROUP BY package_attempts',
1325 array('integer','integer'),
1326 array($this->slm->getId(),$ilUser->getId()));
1327 $val_rec = $ilDB->fetchAssoc($res);
1328 if ($val_rec["cnt"] == 0) { //offline_mode could be inserted
1329 $attempts = 1;
1330 $ilDB->manipulateF(
1331 'INSERT INTO sahs_user (obj_id,user_id,package_attempts,module_version,last_access) VALUES(%s,%s,%s,%s,%s)',
1332 array('integer', 'integer', 'integer', 'integer', 'timestamp'),
1333 array($this->slm->getId(), $ilUser->getId(), $attempts, $this->slm->getModuleVersion(), date('Y-m-d H:i:s')));
1334 } else {
1335 $attempts = $val_rec["package_attempts"];
1336 if ($attempts == null) $attempts = 0;
1337 $attempts++;
1338 $ilDB->manipulateF(
1339 'UPDATE sahs_user SET package_attempts = %s, module_version = %s, last_access=%s WHERE obj_id = %s AND user_id = %s ',
1340 array('integer', 'integer', 'timestamp', 'integer', 'integer'),
1341 array($attempts, $this->slm->getModuleVersion(), date('Y-m-d H:i:s'), $this->slm->getId(), $ilUser->getId()));
1342 }
1343 }
1344
1346 {
1347 global $ilDB;
1348 //Reset the shared data stores if sharedDataGlobalToSystem is false
1349 $res = $ilDB->queryF('
1350 SELECT shared_data_global_to_system
1351 FROM cp_package
1352 WHERE obj_id = %s',
1353 array('integer'),
1354 array($this->packageId)
1355 );
1356
1357 $shared_global_to_sys = $ilDB->fetchObject($res)->shared_data_global_to_system;
1358
1359 $res = $ilDB->queryF('
1360 SELECT data
1361 FROM cp_suspend
1362 WHERE obj_id = %s
1363 AND user_id = %s',
1364 array('integer', 'integer'),
1365 array($this->packageId, $this->userId)
1366 );
1367
1368 $suspended = false;
1369
1370 $dat = $ilDB->fetchObject($res)->data;
1371 if($dat != null && $dat != '' ) $suspended = true;
1372
1373 if($shared_global_to_sys == 0 && !$suspended)
1374 {
1375 $ilDB->manipulateF('
1376 DELETE FROM adl_shared_data
1377 WHERE slm_id = %s
1378 AND user_id = %s',
1379 array('integer', 'integer'),
1380 array($this->packageId, $this->userId)
1381 );
1382 }
1383 }
1384
1385 //debug extentions
1386
1387 private function getNodeData($sco_id,$fh)
1388 {
1389 global $ilDB,$ilLog;
1390
1391 $fieldList = "cmi_node.cp_node_id, cmi_node.completion_threshold, cmi_node.c_exit, cmi_node.completion_status, cmi_node.progress_measure, cmi_node.success_status, cmi_node.scaled, cmi_node.session_time,".
1392 "cmi_node.c_min, cmi_node.c_max, cmi_node.c_raw, cmi_node.location, cmi_node.suspend_data, cmi_node.scaled_passing_score, cmi_node.total_time";
1393
1394
1395 $res = $ilDB->queryF('
1396 SELECT '.$fieldList.'
1397 FROM cmi_node,cp_node,cp_item
1398 WHERE cp_node.slm_id = %s
1399 AND cp_node.cp_node_id = cp_item.cp_node_id
1400 AND cp_item.id = %s
1401 AND cmi_node.cp_node_id = cp_item.cp_node_id
1402 AND cmi_node.user_id = %s',
1403 array('integer','text','integer'),
1404 array($this->packageId, $sco_id, $this->userId)
1405 );
1406 $row = $ilDB->fetchAssoc($res);
1407 $ilLog->write("DEBUG SQL".$row);
1408 return $row;
1409 }
1410
1411 private function logTmpName()
1412 {
1413 $filename = $this->logDirectory()."/".$this->packageId.".tmp";
1414 if (!file_exists($filename)) {
1415 umask(0000);
1416 $fHandle = fopen($filename, 'a') or die("can't open file");
1417 fwrite($fHandle, $string);
1418 fclose($fHandle);
1419 }
1420 return $filename;
1421 }
1422
1423 private function summaryFileName()
1424 {
1425 $filename = $this->logDirectory()."/".$this->packageId."_summary_".$this->get_actual_attempts();
1426 $adder = "0";
1427 $suffix = ".csv";
1428 $i = 0;
1429 while (file_exists($filename."_".$adder.$suffix)) {
1430 $i++;
1431 $adder = (string) $i;
1432 }
1433 $retname = $filename."_".$adder.$suffix;
1434
1435 if (!file_exists($retname)) {
1436 umask(0000);
1437 $fHandle = fopen($retname, 'a') or die("can't open file");
1438 fwrite($fHandle, $string);
1439 fclose($fHandle);
1440 }
1441 return $retname;
1442 }
1443
1444 private function logFileName()
1445 {
1446 global $lng;
1447 $lng->loadLanguageModule("scormdebug");
1448
1449 $filename = $this->logDirectory()."/".$this->packageId."_".$this->get_actual_attempts();
1450 $path_csv = $filename.".csv";
1451 $path_txt = $filename.".html";
1452 if (!file_exists($path_csv)) {
1453 umask(0000);
1454 $fHandle = fopen($path_csv, 'a') or die("can't open file");
1455 $string = '"CourseId";"ScoId";"ScoTitle";"Timestamp";"Action";"Key";"Value";"Return Value";"Errorcode";"Timespan";"ErrorDescription"'."\n";
1456 fwrite($fHandle, $string);
1457 fclose($fHandle);
1458 }
1459 if (!file_exists($path_txt)) {
1460 if (file_exists($this->logTmpName())) {
1461 unlink($this->logTmpName());
1462 }
1463 umask(0000);
1464 $fHandle2 = fopen($path_txt, 'a') or die("can't open file");
1465 $logtpl = $this->getLogTemplate();
1466 $logtpl->setCurrentBlock('NewLog');
1467 $logtpl->setVariable("COURSETITLE", $this->slm->getTitle());
1468 $logtpl->setVariable("COURSEID", $this->packageId);
1469 $logtpl->setVariable("TIMESTAMP", date("d.m.Y H:i",time()));
1470 $logtpl->setVariable("SESSION", $this->get_actual_attempts());
1471 $logtpl->setVariable("error0", $lng->txt("error0"));
1472 $logtpl->setVariable("error101", $lng->txt("error101"));
1473 $logtpl->setVariable("error102", $lng->txt("error102"));
1474 $logtpl->setVariable("error103", $lng->txt("error103"));
1475 $logtpl->setVariable("error104", $lng->txt("error104"));
1476 $logtpl->setVariable("error111", $lng->txt("error111"));
1477 $logtpl->setVariable("error112", $lng->txt("error112"));
1478 $logtpl->setVariable("error113", $lng->txt("error113"));
1479 $logtpl->setVariable("error122", $lng->txt("error122"));
1480 $logtpl->setVariable("error123", $lng->txt("error123"));
1481 $logtpl->setVariable("error132", $lng->txt("error132"));
1482 $logtpl->setVariable("error133", $lng->txt("error133"));
1483 $logtpl->setVariable("error142", $lng->txt("error142"));
1484 $logtpl->setVariable("error143", $lng->txt("error143"));
1485 $logtpl->setVariable("error201", $lng->txt("error201"));
1486 $logtpl->setVariable("error301", $lng->txt("error301"));
1487 $logtpl->setVariable("error351", $lng->txt("error351"));
1488 $logtpl->setVariable("error391", $lng->txt("error391"));
1489 $logtpl->setVariable("error401", $lng->txt("error401"));
1490 $logtpl->setVariable("error402", $lng->txt("error402"));
1491 $logtpl->setVariable("error403", $lng->txt("error403"));
1492 $logtpl->setVariable("error404", $lng->txt("error404"));
1493 $logtpl->setVariable("error405", $lng->txt("error405"));
1494 $logtpl->setVariable("error406", $lng->txt("error406"));
1495 $logtpl->setVariable("error407", $lng->txt("error407"));
1496 $logtpl->setVariable("error408", $lng->txt("error408"));
1497 $logtpl->setVariable("SetValue", $lng->txt("SetValue"));
1498 $logtpl->setVariable("GetValue", $lng->txt("GetValue"));
1499 $logtpl->setVariable("Commit", $lng->txt("Commit"));
1500 $logtpl->setVariable("Initialize", $lng->txt("Initialize"));
1501 $logtpl->setVariable("Terminate", $lng->txt("Terminate"));
1502 $logtpl->setVariable("GetErrorString", $lng->txt("GetErrorString"));
1503 $logtpl->setVariable("GetLastError", $lng->txt("GetLastError"));
1504 $logtpl->setVariable("GetDiagnostic", $lng->txt("GetDiagnostic"));
1505 $logtpl->setVariable("cmi._version", $lng->txt("cmi._version"));
1506 $logtpl->setVariable("cmi.comments_from_learner._children", $lng->txt("cmi.comments_from_learner._children"));
1507 $logtpl->setVariable("cmi.comments_from_learner._count", $lng->txt("cmi.comments_from_learner._count"));
1508 $logtpl->setVariable("cmi.comments_from_learner.n.comment", $lng->txt("cmi.comments_from_learner.n.comment"));
1509 $logtpl->setVariable("cmi.comments_from_learner.n.location", $lng->txt("cmi.comments_from_learner.n.location"));
1510 $logtpl->setVariable("cmi.comments_from_learner.n.timestamp", $lng->txt("cmi.comments_from_learner.n.timestamp"));
1511 $logtpl->setVariable("cmi.comments_from_lms._children", $lng->txt("cmi.comments_from_lms._children"));
1512 $logtpl->setVariable("cmi.comments_from_lms._count", $lng->txt("cmi.comments_from_lms._count"));
1513 $logtpl->setVariable("cmi.comments_from_lms.n.comment", $lng->txt("cmi.comments_from_lms.n.comment"));
1514 $logtpl->setVariable("cmi.comments_from_lms.n.location", $lng->txt("cmi.comments_from_lms.n.location"));
1515 $logtpl->setVariable("cmi.comments_from_lms.n.timestamp", $lng->txt("cmi.comments_from_lms.n.timestamp"));
1516 $logtpl->setVariable("cmi.completion_status", $lng->txt("cmi.completion_status"));
1517 $logtpl->setVariable("cmi.completion_threshold", $lng->txt("cmi.completion_threshold"));
1518 $logtpl->setVariable("cmi.credit", $lng->txt("cmi.credit"));
1519 $logtpl->setVariable("cmi.entry", $lng->txt("cmi.entry"));
1520 $logtpl->setVariable("cmi.exit", $lng->txt("cmi.exit"));
1521 $logtpl->setVariable("cmi.interactions._children", $lng->txt("cmi.interactions._children"));
1522 $logtpl->setVariable("cmi.interactions._count", $lng->txt("cmi.interactions._count"));
1523 $logtpl->setVariable("cmi.interactions.n.id", $lng->txt("cmi.interactions.n.id"));
1524 $logtpl->setVariable("cmi.interactions.n.type", $lng->txt("cmi.interactions.n.type"));
1525 $logtpl->setVariable("cmi.interactions.n.objectives._count", $lng->txt("cmi.interactions.n.objectives._count"));
1526 $logtpl->setVariable("cmi.interactions.n.objectives.n.id", $lng->txt("cmi.interactions.n.objectives.n.id"));
1527 $logtpl->setVariable("cmi.interactions.n.timestamp", $lng->txt("cmi.interactions.n.timestamp"));
1528 $logtpl->setVariable("cmi.interactions.n.correct_responses._count", $lng->txt("cmi.interactions.n.correct_responses._count"));
1529 $logtpl->setVariable("cmi.interactions.n.correct_responses.n.pattern", $lng->txt("cmi.interactions.n.correct_responses.n.pattern"));
1530 $logtpl->setVariable("cmi.interactions.n.weighting", $lng->txt("cmi.interactions.n.weighting"));
1531 $logtpl->setVariable("cmi.interactions.n.learner_response", $lng->txt("cmi.interactions.n.learner_response"));
1532 $logtpl->setVariable("cmi.interactions.n.result", $lng->txt("cmi.interactions.n.result"));
1533 $logtpl->setVariable("cmi.interactions.n.latency", $lng->txt("cmi.interactions.n.latency"));
1534 $logtpl->setVariable("cmi.interactions.n.description", $lng->txt("cmi.interactions.n.description"));
1535 $logtpl->setVariable("cmi.launch_data", $lng->txt("cmi.launch_data"));
1536 $logtpl->setVariable("cmi.learner_id", $lng->txt("cmi.learner_id"));
1537 $logtpl->setVariable("cmi.learner_name", $lng->txt("cmi.learner_name"));
1538 $logtpl->setVariable("cmi.learner_preference._children", $lng->txt("cmi.learner_preference._children"));
1539 $logtpl->setVariable("cmi.learner_preference.audio_level", $lng->txt("cmi.learner_preference.audio_level"));
1540 $logtpl->setVariable("cmi.learner_preference.language", $lng->txt("cmi.learner_preference.language"));
1541 $logtpl->setVariable("cmi.learner_preference.delivery_speed", $lng->txt("cmi.learner_preference.delivery_speed"));
1542 $logtpl->setVariable("cmi.learner_preference.audio_captioning", $lng->txt("cmi.learner_preference.audio_captioning"));
1543 $logtpl->setVariable("cmi.location", $lng->txt("cmi.location"));
1544 $logtpl->setVariable("cmi.max_time_allowed", $lng->txt("cmi.max_time_allowed"));
1545 $logtpl->setVariable("cmi.mode", $lng->txt("cmi.mode"));
1546 $logtpl->setVariable("cmi.objectives._children", $lng->txt("cmi.objectives._children"));
1547 $logtpl->setVariable("cmi.objectives._count", $lng->txt("cmi.objectives._count"));
1548 $logtpl->setVariable("cmi.objectives.n.id", $lng->txt("cmi.objectives.n.id"));
1549 $logtpl->setVariable("cmi.objectives.n.score._children", $lng->txt("cmi.objectives.n.score._children"));
1550 $logtpl->setVariable("cmi.objectives.n.score.scaled", $lng->txt("cmi.objectives.n.score.scaled"));
1551 $logtpl->setVariable("cmi.objectives.n.score.raw", $lng->txt("cmi.objectives.n.score.raw"));
1552 $logtpl->setVariable("cmi.objectives.n.score.min", $lng->txt("cmi.objectives.n.score.min"));
1553 $logtpl->setVariable("cmi.objectives.n.score.max", $lng->txt("cmi.objectives.n.score.max"));
1554 $logtpl->setVariable("cmi.objectives.n.success_status", $lng->txt("cmi.objectives.n.success_status"));
1555 $logtpl->setVariable("cmi.objectives.n.completion_status", $lng->txt("cmi.objectives.n.completion_status"));
1556 $logtpl->setVariable("cmi.objectives.n.progress_measure", $lng->txt("cmi.objectives.n.progress_measure"));
1557 $logtpl->setVariable("cmi.objectives.n.description", $lng->txt("cmi.objectives.n.description"));
1558 $logtpl->setVariable("cmi.progress_measure", $lng->txt("cmi.progress_measure"));
1559 $logtpl->setVariable("cmi.scaled_passing_score", $lng->txt("cmi.scaled_passing_score"));
1560 $logtpl->setVariable("cmi.score._children", $lng->txt("cmi.score._children"));
1561 $logtpl->setVariable("cmi.score.scaled", $lng->txt("cmi.score.scaled"));
1562 $logtpl->setVariable("cmi.score.raw", $lng->txt("cmi.score.raw"));
1563 $logtpl->setVariable("cmi.score.min", $lng->txt("cmi.score.min"));
1564 $logtpl->setVariable("cmi.score.max", $lng->txt("cmi.score.max"));
1565 $logtpl->setVariable("cmi.session_time", $lng->txt("cmi.session_time"));
1566 $logtpl->setVariable("cmi.success_status", $lng->txt("cmi.success_status"));
1567 $logtpl->setVariable("cmi.suspend_data", $lng->txt("cmi.suspend_data"));
1568 $logtpl->setVariable("cmi.time_limit_action", $lng->txt("cmi.time_limit_action"));
1569 $logtpl->setVariable("cmi.total_time", $lng->txt("cmi.total_time"));
1570 $logtpl->setVariable("adl.nav.request", $lng->txt("adl.nav.request"));
1571 $logtpl->setVariable("adl.nav.request_valid.continue", $lng->txt("adl.nav.request_valid.continue"));
1572 $logtpl->setVariable("adl.nav.request_valid.previous", $lng->txt("adl.nav.request_valid.previous"));
1573 $logtpl->setVariable("adl.nav.request_valid.choice", $lng->txt("adl.nav.request_valid.choice"));
1574 $logtpl->setVariable("i_green", $lng->txt("i_green"));
1575 $logtpl->setVariable("i_red", $lng->txt("i_red"));
1576 $logtpl->setVariable("i_orange", $lng->txt("i_orange"));
1577 $logtpl->setVariable("i_fuchsia", $lng->txt("i_fuchsia"));
1578 $logtpl->setVariable("i_gray", $lng->txt("i_gray"));
1579 $logtpl->setVariable("error", $lng->txt("error"));
1580 $logtpl->setVariable("strange_error", $lng->txt("strange_error"));
1581 $logtpl->setVariable("strange_API-Call", $lng->txt("strange_API-Call"));
1582 $logtpl->setVariable("unknown", $lng->txt("unknown"));
1583 $logtpl->setVariable("undefined_color", $lng->txt("undefined_color"));
1584 $logtpl->setVariable("description_for", $lng->txt("description_for"));
1585 $logtpl->setVariable("hide", $lng->txt("hide"));
1586 $logtpl->setVariable("all_API-calls_shown", $lng->txt("all_API-calls_shown"));
1587 $logtpl->setVariable("show_only_important_API-calls", $lng->txt("show_only_important_API-calls"));
1588 $logtpl->setVariable("only_important_API-Calls_shown", $lng->txt("only_important_API-Calls_shown"));
1589 $logtpl->setVariable("show_all_API-calls", $lng->txt("show_all_API-calls"));
1590 $logtpl->setVariable("log_for", $lng->txt("log_for"));
1591 $logtpl->setVariable("started", $lng->txt("started"));
1592 $logtpl->setVariable("nr_session", $lng->txt("nr_session"));
1593 $logtpl->setVariable("id_learning_module", $lng->txt("id_learning_module"));
1594 if($this->slm->getCheck_values()==false) $logtpl->setVariable("CHECK_VALUES", $lng->txt("sent_values_not_checked"));
1595 $logtpl->parseCurrentBlock();
1596 fwrite($fHandle2,$logtpl->get());
1597 fclose($fHandle2);
1598 }
1599 return $filename;
1600 }
1601
1603 {
1604 $webdir=str_replace("/ilias.php","",$_SERVER["SCRIPT_NAME"]);
1605 //load ressources always with absolute URL..relative URLS fail on innersco navigation on certain browsers
1606 $lm_dir=$webdir."/".ILIAS_WEB_DIR."/".$this->ilias->client_id ."/lm_data"."/lm_".$this->packageId;
1607 return $lm_dir;
1608 }
1609
1610 private function logDirectory()
1611 {
1612// $logDir=ilUtil::getDataDir()."/SCORMlogs"."/lm_".$this->packageId;
1613// if (!file_exists($logDir)) ilUtil::makeDirParents($logDir);
1614 $logDir=$this->slm->getDataDirectory()."/logs";
1615 if (!file_exists($logDir)) {
1616 ilUtil::makeDir($logDir);
1617 }
1618 return $logDir;
1619 }
1620
1621 public function openLog(){
1622 $filename = $_GET['logFile'];
1623 //Header
1624 header('Content-Type: text/html; charset=UTF-8');
1625 echo file_get_contents($this->logDirectory()."/".$filename);
1626 exit;
1627 }
1628
1629 public function downloadLog(){
1630 $filename = $_GET['logFile'];
1631 //Header
1632 header("Expires: 0");
1633 header("Cache-Control: private");
1634 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
1635 header("Pragma: cache");
1636 header("Content-Description: File Transfer");
1637 header("Content-Type: application/octet-stream");
1638 header("Content-disposition: attachment; filename=$filename");
1639 echo file_get_contents($this->logDirectory()."/".$filename);
1640 exit;
1641 }
1642
1643 private function getLogFileList($s_delete,$s_download,$s_open)
1644 {
1645 $data = array();
1646 foreach (new DirectoryIterator($this->logDirectory()) as $fileInfo) {
1647 if ($fileInfo->isDot()) {
1648 continue;
1649 }
1650 $item['filename'] = $fileInfo->getFilename();
1651 $parts = pathinfo($item['filename']);
1652 $fnameparts = preg_split('/_/', $parts['filename'], -1, PREG_SPLIT_NO_EMPTY);
1653 $deleteUrl = '&nbsp;<a href=#'." onclick=\"javascript:deleteFile('".$item['filename']."');\">".$s_delete."</a>";
1654 //no delete for most recent file
1655 if ($this->get_actual_attempts()==$fnameparts[1]) {$deleteUrl="";}
1656
1657 $urlDownload = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=downloadLog&ref_id='.$_GET["ref_id"].'&logFile='.$fileInfo->getFilename();
1658 $urlOpen = 'ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=openLog&ref_id='.$_GET["ref_id"].'&logFile='.$fileInfo->getFilename();
1659 $item['date'] = date('Y/m/d H:i:s', $fileInfo->getCTime());
1660 if ($parts['extension'] == "html") {
1661 $item['action'] =$deleteUrl."&nbsp;<a href=".$urlDownload.">".$s_download."</a>&nbsp;<a target=_new href=".$urlOpen.">".$s_open."</a>";
1662 } else {
1663 $item['action'] =$deleteUrl."&nbsp;<a href=".$urlDownload.">".$s_download."</a>";
1664 }
1665 if ($parts['extension'] == "html" || $parts['extension'] == "csv") {
1666 array_push($data,$item);
1667 }
1668 }
1669 usort($data,"datecmp");
1670 return $data;
1671 }
1672
1673 public function liveLogContent()
1674 {
1675 header('Content-Type: text/html; charset=UTF-8');
1676 print file_get_contents($this->logFileName().".html");
1677 }
1678
1679 public function debugGUI()
1680 {
1681 global $lng;
1682 $lng->loadLanguageModule("scormdebug");
1683
1684/* if ($_POST['password'] == $this->slm->getDebugPw()) {
1685 $_SESSION["debug_pw"] = $this->slm->getDebugPw();
1686 }
1687 if ($_SESSION["debug_pw"]!=$this->slm->getDebugPw()) {
1688 $this->tpl = new ilTemplate("tpl.scorm2004.debug_pw.html", false, false, "./Modules/Scorm2004");
1689 $this->tpl->setVariable('SUBMIT', $lng->txt("debugwindow_submit"));
1690 $this->tpl->setVariable('CANCEL', $lng->txt("debugwindow_cancel"));
1691 $this->tpl->setVariable('PASSWORD_ENTER', $lng->txt("debugwindow_password_enter"));
1692 $this->tpl->setVariable('DEBUG_URL','ilias.php?baseClass=ilSAHSPresentationGUI' .'&cmd=debugGUI&ref_id='.$_GET["ref_id"]);
1693 } else {*/
1694 $this->tpl = new ilTemplate("tpl.scorm2004.debug.html", false, false, "./Modules/Scorm2004");
1695 $this->tpl->setVariable('CONSOLE', $lng->txt("debugwindow_console"));
1696 $this->tpl->setVariable('LOGS', $lng->txt("debugwindow_logs"));
1697 $this->tpl->setVariable('COMMENT', $lng->txt("debugwindow_comment"));
1698 $this->tpl->setVariable('COMMENT_ENTER', $lng->txt("debugwindow_comment_enter"));
1699 $this->tpl->setVariable('START_RECORDING', $lng->txt("debugwindow_start_recording"));
1700 $this->tpl->setVariable('STOP_RECORDING', $lng->txt("debugwindow_stop_recording"));
1701 $this->tpl->setVariable('DELETE_LOGFILE', $lng->txt("debugwindow_delete_logfile"));
1702 $this->tpl->setVariable('SUBMISSION_FAILED', $lng->txt("debugwindow_submission_failed"));
1703 $this->tpl->setVariable('SUBMIT', $lng->txt("debugwindow_submit"));
1704 $this->tpl->setVariable('CANCEL', $lng->txt("debugwindow_cancel"));
1705 $this->tpl->setVariable('FILENAME', $lng->txt("debugwindow_filename"));
1706 $this->tpl->setVariable('DATE', $lng->txt("debugwindow_date"));
1707 $this->tpl->setVariable('ACTION', $lng->txt("debugwindow_action"));
1708 $this->tpl->setVariable('RECORD_IMG', ilUtil::getImagePath("record.png","./Modules/Scorm2004"));
1709 $this->tpl->setVariable('STOP_IMG', ilUtil::getImagePath("stop.png","./Modules/Scorm2004"));
1710 $this->tpl->setVariable('COMMENT_IMG', ilUtil::getImagePath("comment.png","./Modules/Scorm2004"));
1711 $logfile = $this->logFileName().".html";
1712 $this->tpl->setVariable('LOGFILE',$this->logFileName().".html");
1713 $this->tpl->setVariable('FILES_DATA', json_encode($this->getLogFileList($lng->txt("debugwindow_delete"), $lng->txt("debugwindow_download"), $lng->txt("debugwindow_open"))));
1714
1715 // path to latest yui distribution
1716 include_once "Services/YUI/classes/class.ilYuiUtil.php";
1717 $this->tpl->setVariable('PATH_YUI', ilYuiUtil::getLocalPath());
1718 //}
1719 echo $this->tpl->get("DEFAULT", true);
1720 }
1721
1722 private function getLogTemplate()
1723 {
1724 return new ilTemplate("tpl.scorm2004.debugtxt.txt", true, true, "Modules/Scorm2004");
1725 }
1726
1727 private function getDebugValues($test_sco = false)
1728 {
1729 global $ilDB,$ilLog;
1730 $ini_array = null;
1731 $dvalues = array();
1732/*
1733 $res = $ilDB->queryF('
1734 SELECT debug_fields
1735 FROM sahs_lm
1736 WHERE id = %s',
1737 array('integer'),
1738 array($this->packageId)
1739 );
1740 $row = $ilDB->fetchAssoc($res);
1741 $debug_fields = $row['debug_fields'];
1742 if ($debug_fields == null) {*/
1743 $debug_fields = parse_ini_file("./Modules/Scorm2004/scripts/rtemain/debug_default.ini",true);
1744// }
1745 if ($test_sco) {
1746 $ini_array = $debug_fields['test_sco'];
1747 } else {
1748 $ini_array = $debug_fields['normal_sco'];
1749 }
1750 foreach ($ini_array as $key => $value) {
1751 if ($value == 1) {
1752 array_push($dvalues,$key);
1753 }
1754 }
1755 return $dvalues;
1756 }
1757
1758 public function postLogEntry()
1759 {
1760 global $ilLog,$lng;
1761 $lng->loadLanguageModule("scormdebug");
1762
1763 $logdata = json_decode(file_get_contents('php://input'));
1764 $filename = $this->logFileName();
1765 $tmp_name = $this->logTmpName();
1766
1767 $fh_txt = fopen($filename.".html", 'a') or die("can't open txt file");
1768 $fh_csv = fopen($filename.".csv", 'a') or die("can't open csv file");
1769 $fh_tmp = fopen($tmp_name, 'r') or die("can't open tmp file");
1770
1771 //init tmp file
1772 if (filesize($tmp_name)>0) {
1773 $tmp_content = unserialize(fread($fh_tmp,filesize($tmp_name)));
1774 } else {
1775 $tmp_content = null;
1776 }
1777
1778 fclose($fh_tmp);
1779
1780 //reopen for writing
1781 $fh_tmp2 = fopen($tmp_name, 'w') or die("can't open tmp file");
1782
1783
1784 //write tmp
1785 $tmp_content[$logdata->scoid][$logdata->key]['value'] = $logdata->value;
1786 $tmp_content[$logdata->scoid][$logdata->key]['status'] = $logdata->result;
1787 $tmp_content[$logdata->scoid][$logdata->key]['action'] = $logdata->action;
1788
1789 fwrite($fh_tmp2,serialize($tmp_content));
1790 fclose($fh_tmp2);
1791
1792 $timestamp = date("d.m.Y H:i",time());
1793
1794
1795 $errorcode = $logdata->errorcode;
1796 $fixedFailure = false;
1797 $toleratedFailure = false;
1798 $extraErrorDescription = "";
1799 if ($errorcode == 200000) {
1800 $errorcode = 0;
1801 $toleratedFailure = true;
1802 $extraErrorDescription = "tolerated failure";
1803 }
1804 if ($errorcode>99999) {
1805 $errorcode-=100000;
1806 $fixedFailure = true;
1807 $extraErrorDescription = " failure corrected by ILIAS";
1808 }
1809 if (strpos($logdata->action,"ANALYZE")===false)
1810 {
1811 $errorDescriptions = array("0" => "",
1812 "101" => "General Exeption",
1813 "102" => "General Initialization Failure",
1814 "103" => "Already Initialized",
1815 "104" => "Content Instance Terminated",
1816 "111" => "General Termination Failure",
1817 "112" => "Termination Before Initialization",
1818 "113" => "Termination After Termination",
1819 "122" => "Retrieve Data Before Initialization",
1820 "123" => "Retrieve Data After Termination",
1821 "132" => "Store Data Before Initialization",
1822 "133" => "Store Data After Termination",
1823 "142" => "Commit Before Initialization",
1824 "143" => "Commit After Termination",
1825 "201" => "General Argument Error",
1826 "301" => "General Get Failure",
1827 "351" => "General Set Failure",
1828 "391" => "General Commit Failure",
1829 "401" => "Undefined Data Model Element",
1830 "402" => "Unimplemented Data Model Element",
1831 "403" => "Data Model Element Value Not Initialized",
1832 "404" => "Data Model Element Is Read Only",
1833 "405" => "Data Model Element Is Write Only",
1834 "406" => "Data Model Element Type Mismatch",
1835 "407" => "Data Model Element Value Out Of Range",
1836 "408" => "Data Model Dependency Not Established");
1837 $csv_string = $this->packageId.';"'
1838 .$logdata->scoid.'";"'
1839 .$logdata->scotitle.'";'
1840 .date("d.m.Y H:i",time()).';"'
1841 .$logdata->action.'";"'
1842 .$logdata->key.'";"'
1843 .str_replace("\"","\"\"",$logdata->value).'";"'
1844 .str_replace("\"","\"\"",$logdata->result).'";'
1845 .$errorcode.';'
1846 .$logdata->timespan.';"'
1847 .$errorDescriptions[$errorcode].$extraErrorDescription.'"'."\n";
1848 fwrite($fh_csv,$csv_string);
1849 }
1850
1851 $sqlwrite = false;
1852 if($logdata->action == "Commit" || $logdata->action == "Terminate")
1853 {
1854 $sqlwrite = true;
1855 $sql_data = $this->getNodeData($logdata->scoid,$fh_csv);
1856 foreach ($sql_data as $key => $value) {
1857 $sql_string = $this->packageId.';"'
1858 .$logdata->scoid.'";"'
1859 .$logdata->scotitle.'";'
1860 .$timestamp.';"SQL";"'
1861 .$key.'";"'
1862 .str_replace("\"","\"\"",$value).'";;;;'."\n";
1863 fwrite($fh_csv,$sql_string);
1864 }
1865 }
1866
1867 //delete files
1868 if ($logdata->action == "DELETE")
1869 {
1870 $filename = $logdata->value;
1871 $path = $this->logDirectory()."/".$filename;
1872 unlink($path);
1873 return;
1874 }
1875
1876 //write TXT
1877 $logtpl = $this->getLogTemplate();
1878 $color = "red";
1879 $importantkey=1;
1880 $ArGetValues = array('comments_from_lms','completion_threshold','credit','entry','launch_data','learner_id','learner_name','max_time_allowed','mode','scaled_passing_score','time_limit_action','total_time');
1881
1882 switch ($logdata->action) {
1883 case 'SetValue':
1884 if ($logdata->result == "true" && $errorcode == 0) $color = "green";
1885 if ($color=="green" && $logdata->key == "cmi.exit" && $logdata->value!="suspend") $color = "orange";
1886 if ($fixedFailure == false && $errorcode!=406) $logdata->value = '"'.$logdata->value.'"';
1887 if ($toleratedFailure == true) $color = "fuchsia";
1888 if ($fixedFailure == true) $color = "gray";
1889 break;
1890 case 'GetValue':
1891 if ($errorcode == 0) $color = "green";
1892 break;
1893 case 'Initialize':
1894 if ($errorcode == 0)
1895 {
1896 $color = "green";
1897 $logtpl->setCurrentBlock("InitializeStart");
1898 $logtpl->setVariable("SCO-title", $lng->txt("SCO-title"));
1899 $logtpl->setVariable("SCO_TITLE", $logdata->scotitle);
1900 $logtpl->setVariable("SCO-name", $lng->txt("SCO-name"));
1901 $logtpl->setVariable("SCO_NAME", $logdata->scoid);
1902 $logtpl->setVariable("started", $lng->txt("started"));
1903 $logtpl->setVariable("TIMESTAMP", $timestamp);
1904 $logtpl->setVariable("milliseconds", $lng->txt("milliseconds"));
1905 $logtpl->setVariable("API-call", $lng->txt("API-call"));
1906 $logtpl->setVariable("return_value", $lng->txt("return_value"));
1907 $logtpl->setVariable("error", $lng->txt("error"));
1908 $logtpl->parseCurrentBlock();
1909 }
1910 break;
1911 case 'Commit':
1912 if ($errorcode == 0) $color = "green";
1913 if ($fixedFailure == true) $color = "gray";
1914 break;
1915 case 'Terminate':
1916 if ($errorcode == 0) $color = "green";
1917 break;
1918 case 'GetErrorString':
1919 $importantkey=0;
1920 if ($errorcode == 0) $color = "green";
1921 break;
1922 case 'GetLastError':
1923 $logtpl->setCurrentBlock("GetLastError");
1924 $logtpl->setVariable("TIMESPAN", $logdata->timespan);
1925 $logtpl->setVariable("RESULT", $logdata->result);
1926 $logtpl->parseCurrentBlock();
1927 break;
1928 case 'GetDiagnostic':
1929 $logtpl->setCurrentBlock("GetDiagnostic");
1930 $logtpl->setVariable("TIMESPAN", $logdata->timespan);
1931 $logtpl->setVariable("KEY", $logdata->key);
1932 $logtpl->setVariable("RESULT", $logdata->result);
1933 $logtpl->parseCurrentBlock();
1934 break;
1935 case 'INFO':
1936 $logtpl->setCurrentBlock("INFO");
1937 $logtpl->setVariable("hint", $lng->txt("hint"));
1938 $logtpl->setVariable("KEY", $lng->txt($logdata->key));
1939 $logtpl->setVariable("VALUE", $logdata->value);
1940 $logtpl->parseCurrentBlock();
1941 break;
1942 case 'COMMENT':
1943 $logtpl->setCurrentBlock("COMMENT");
1944 $logtpl->setVariable("comment", $lng->txt("comment"));
1945 $logtpl->setVariable("generated", $lng->txt("generated"));
1946 $logtpl->setVariable("TIMESTAMP", $timestamp);
1947 $logtpl->setVariable("VALUE", $logdata->value);
1948 $logtpl->parseCurrentBlock();
1949 break;
1950 case 'ANALYZE':
1951 $logtpl->setCurrentBlock("ANALYZE");
1952 if (count($logdata->value) == 0) {
1953 $color = "green";
1954 $logtpl->setVariable("ANALYZE_SUMMARY", $lng->txt("no_missing_API-calls"));
1955 $logtpl->setVariable("VALUE", "");
1956 } else {
1957 $tmpvalue = "SetValue(\"".implode("\", ... ),<br/>SetValue(\"",$logdata->value)."\", ... )";
1958 for ($i=0; $i <count($ArGetValues); $i++){
1959 $tmpvalue = str_replace("SetValue(\"cmi.".$ArGetValues[$i]."\", ... )","GetValue(\"cmi.".$ArGetValues[$i]."\")",$tmpvalue);
1960 }
1961 $logtpl->setVariable("ANALYZE_SUMMARY", $lng->txt("missing_API-calls"));
1962 $logtpl->setVariable("VALUE", $tmpvalue);
1963 }
1964 $logtpl->setVariable("summary_for_SCO_without_test", $lng->txt("summary_for_SCO_without_test"));
1965 $logtpl->setVariable("generated", $lng->txt("generated"));
1966 $logtpl->setVariable("TIMESTAMP", $timestamp);
1967 $logtpl->setVariable("COLOR", $color);
1968 $logtpl->parseCurrentBlock();
1969 break;
1970 case 'ANALYZETEST':
1971 $logtpl->setCurrentBlock("ANALYZETEST");
1972 if (count($logdata->value) == 0) {
1973 $color = "green";
1974 $logtpl->setVariable("ANALYZE_SUMMARY", $lng->txt("no_missing_API-calls"));
1975 $logtpl->setVariable("VALUE", "");
1976 } else {
1977 $tmpvalue = "SetValue(\"".implode("\", ... ),<br/>SetValue(\"",$logdata->value)."\", ... )";
1978 for ($i=0; $i <count($ArGetValues); $i++){
1979 $tmpvalue = str_replace("SetValue(\"cmi.".$ArGetValues[$i]."\", ... )","GetValue(\"cmi.".$ArGetValues[$i]."\")",$tmpvalue);
1980 }
1981 $logtpl->setVariable("ANALYZE_SUMMARY", $lng->txt("missing_API-calls"));
1982 $logtpl->setVariable("VALUE", $tmpvalue);
1983 }
1984 $logtpl->setVariable("summary_for_SCO_with_test", $lng->txt("summary_for_SCO_with_test"));
1985 $logtpl->setVariable("generated", $lng->txt("generated"));
1986 $logtpl->setVariable("TIMESTAMP", $timestamp);
1987 $logtpl->setVariable("COLOR", $color);
1988 $logtpl->parseCurrentBlock();
1989 break;
1990 case 'SUMMARY':
1991 $logtpl->setCurrentBlock("SUMMARY");
1992 $logtpl->setVariable("summary_csv", $lng->txt("summary_csv"));
1993 $logtpl->setVariable("TIMESTAMP", $timestamp);
1994 $logtpl->setVariable("summary_download", $lng->txt("summary_download"));
1995 $logtpl->parseCurrentBlock();
1996 break;
1997 default:
1998 $importantkey=0;
1999 $color = "orange";
2000 break;
2001 }
2002 if ($logdata->action == 'SetValue' || $logdata->action == 'GetValue')
2003 {
2004 $logtpl->setCurrentBlock($logdata->action);
2005 $logtpl->setVariable("ACTION", $logdata->action);
2006 $logtpl->setVariable("TIMESPAN", $logdata->timespan);
2007 $logtpl->setVariable("KEY", $logdata->key);
2008 $logtpl->setVariable("VALUE", $logdata->value);
2009 $logtpl->setVariable("RESULT", $logdata->result);
2010 $logtpl->setVariable("ERRORCODE", $errorcode);
2011 $debugfields=$this->getDebugValues(true);
2012 $importantkey=0;
2013 for ($i=0; $i <count($debugfields) ; $i++){
2014 if ($logdata->key == $debugfields[$i]) $importantkey=1;
2015 }
2016 $logtpl->setVariable("IMPORTANTKEY", "".$importantkey);
2017 $logtpl->setVariable("COLOR", $color);
2018 $logtpl->parseCurrentBlock();
2019 }
2020 else if ($logdata->action != 'INFO' && $logdata->action != 'ANALYZE' && $logdata->action != 'ANALYZETEST' && $logdata->action != 'SUMMARY' && $logdata->action != 'COMMENT' && $logdata->action != 'GetDiagnostic' && $logdata->action != 'GetLastError')
2021 {
2022 $logtpl->setCurrentBlock("defaultCall");
2023 $logtpl->setVariable("ACTION", $logdata->action);
2024 $logtpl->setVariable("TIMESPAN", $logdata->timespan);
2025 $logtpl->setVariable("KEY", $logdata->key);
2026 $logtpl->setVariable("VALUE", $logdata->value);
2027 $logtpl->setVariable("RESULT", $logdata->result);
2028 $logtpl->setVariable("ERRORCODE", $errorcode);
2029 $logtpl->setVariable("IMPORTANTKEY", "".$importantkey);
2030 $logtpl->setVariable("COLOR", $color);
2031 $logtpl->parseCurrentBlock();
2032 }
2033
2034 /*
2035 if ($sqlwrite == true) {
2036 $ilLog->write("SQL WRITE");
2037 $logtpl->setCurrentBlock("SqlLog");
2038 $logtpl->setVariable("SQL_STRING", $sql_text);
2039 $logtpl->parseCurrentBlock();
2040 }
2041 */
2042
2043 //create summary
2044 if ($logdata->action == "SUMMARY") {
2045 $this->createSummary($tmp_content);
2046 }
2047
2048 fwrite($fh_txt,$logtpl->get());
2049 fclose($fh_txt);
2050 fclose($fh_csv);
2051 }
2052
2053 private function getStructureFlat($data)
2054 {
2055 for ($i=0; $i <count($data) ; $i++) {
2056 $element = array();
2057 $element['title'] = $data[$i]['title'];
2058 $element['id'] = $data[$i]['id'];
2059 if ($data[$i]['sco'] == 1) {
2060 $element['sco'] = "sco";
2061 } else {
2062 $element['sco'] = "assset";
2063 }
2064 if ( $data[$i]['href'] !=null ) {
2065 array_push($this->flat_structure,$element);
2066 }
2067 if ($data[$i]['item']!=null) {
2068 $this->getStructureFlat($data[$i]['item']);
2069 }
2070 }
2071 }
2072
2073 private function createSummary($api_data)
2074 {
2075 global $ilDB;
2076
2077 $csv_data = null;
2078 //csv columns
2079 $columns_fixed = array('id','title','type','attempted');
2080
2081 $ini_data = parse_ini_file("./Modules/Scorm2004/scripts/rtemain/debug_default.ini",true);
2082 $ini_array = $ini_data['summary'];
2083 $colums_variable = array();
2084 $api_keys = array();
2085
2086 foreach ($ini_array as $key => $value) {
2087 if ($value == 1) {
2088 array_push($colums_variable,$key);
2089 array_push($api_keys,$key);
2090 array_push($colums_variable,"Status");
2091 }
2092 }
2093
2094 $header_array = array_merge($columns_fixed, $colums_variable);
2095
2096 $csv_header = implode(";",$header_array);
2097
2098 //get strcuture
2099 $res = $ilDB->queryF(
2100 'SELECT jsdata FROM cp_package WHERE obj_id = %s',
2101 array('integer'),
2102 array($this->packageId)
2103 );
2104
2105 $packageData = $ilDB->fetchAssoc($res);
2106
2107 $structure = json_decode($packageData['jsdata'],true);
2108
2109
2110 $this->flat_structure = array(); //used for recursion
2111 $this->getStructureFlat($structure['item']['item']);
2112
2113 foreach ($this->flat_structure as $tree_element) {
2114
2115 $csv_data = $csv_data.$tree_element['id'].";".$tree_element['title'].";".$tree_element['sco'].";";
2116 if ($api_data[$tree_element['id']] != null) {
2117 $csv_data = $csv_data."X".";";
2118 } else {
2119 $csv_data = $csv_data.";";
2120 }
2121
2122 //write api data
2123 $id = $tree_element['id'];
2124 foreach ($api_keys as $api_element) {
2125 if ($api_data[$id]!=null) {
2126 if ($api_data[$id][$api_element]!=null) {
2127 $csv_data = $csv_data.$api_data[$id][$api_element]['value'].";".$api_data[$id][$api_element]['status'].";";
2128 } else {
2129 $csv_data = $csv_data.";;";
2130 }
2131 }
2132 }
2133 $csv_data = $csv_data."\n";
2134 }
2135
2136 $fh = fopen($this->summaryFileName(),"w");
2137 fwrite($fh,$csv_header."\n".$csv_data);
2138 fclose($fh);
2139 unlink($this->logTmpName());
2140 }
2145 // function get_last_visited($a_obj_id, $a_user_id)
2146 // {
2147 // global $ilDB;
2148 // $val_set = $ilDB->queryF('SELECT last_visited FROM sahs_user WHERE obj_id = %s AND user_id = %s',
2149 // array('integer','integer'),
2150 // array($a_obj_id,$a_user_id));
2151
2152 // $val_rec = $ilDB->fetchAssoc($val_set);
2153 // return $val_rec["last_visited"];
2154 // }
2155}
2156
2157function datecmp($a, $b){
2158 if (strtotime($a['date']) == strtotime($b['date'])) {
2159 return 0;
2160 }
2161 return (strtotime($a['date']) < strtotime($b['date'])) ? 1 :-1;
2162}
2163
2164?>
$result
$filename
Definition: buildRTE.php:89
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81
$_GET["client_id"]
static getMimeType($a_file, $a_external=false)
get mime type for file
Class ilObjSCORM2004LearningModule.
getStatus($a_packageId, $a_user_id, $auto_last_visited, $scormType="1.2")
get_max_attempts($a_packageId)
Get max.
static _lookupObjectId($a_ref_id)
lookup object id
normalizeFields($table, &$node)
maps API data structure type to internal datatype on a node and accepts only valid values,...
getMimetype($filename)
estimate content type for a filename by extension first do it for common static web files from extern...
getCookie()
getting and setting Scorm2004 cookie Cookie contains enrypted associative array of sahs_lm....
readFile($path)
Try to find file, identify content type, write it to buffer, and stop immediatly If no file given,...
getDebugValues($test_sco=false)
increase_attemptAndsave_module_version()
Increases attempts by one and saves module_version for this package.
getInlineCSS()
Get inline css.
getLogFileList($s_delete, $s_download, $s_open)
getNodeData($sco_id, $fh)
getCMIData($userId, $packageId)
writeSharedData($sco_node_id)
createSummary($api_data)
readSharedData($sco_node_id)
get_max_attempts()
Get max.
quoteJSONArray($a_array)
& executeCommand()
execute command
get_actual_attempts()
Get number of actual attempts for the user.
persistCMIData($userId=null, $packageId, $defaultLessonMode, $comments, $interactions, $objectives, $time_from_lms, $data=null)
scormPlayerUnload($userId=null, $packageId, $time_from_lms)
ILIAS Setting Class.
special template class to simplify handling of ITX/PEAR
static getStyleSheetLocation($mode="output", $a_css_name="", $a_css_location="")
get full style sheet file name (path inclusive) of current user
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
static signFolderOfStartFile($start_file_path, ilWACCookieInterface $ilWACCookieInterface=null)
static getCookieMaxLifetimeInSeconds()
static getLocalPath($a_name="")
Get local path of a YUI js file.
getLocaljQueryPath()
Get local path of jQuery file.
$_COOKIE["ilClientId"]
Definition: cron.php:11
$data
$params
Definition: example_049.php:96
$GLOBALS['PHPCAS_CLIENT']
This global variable is used by the interface class phpCAS.
Definition: CAS.php:276
datecmp($a, $b)
global $ilCtrl
Definition: ilias.php:18
if(! $in) print
exit
Definition: login.php:54
redirection script todo: (a better solution should control the processing via a xml file)
global $lng
Definition: privfeed.php:40
global $ilSetting
Definition: privfeed.php:40
$cmd
Definition: sahs_server.php:35
$path
Definition: index.php:22
if($_REQUEST['ilias_path']) define('ILIAS_HTTP_PATH' $_REQUEST['ilias_path']
Definition: index.php:7
$packageId
global $ilDB
$lm_set
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']
global $ilUser
Definition: imgupload.php:15
const ILIAS_WEB_DIR