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