ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilObjSCORMLearningModuleGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
36 {
38  protected \ILIAS\DI\Container $dic;
39 
40  protected int $refId;
41  protected ilCtrl $ctrl;
42 
46  public function __construct($data, int $id, bool $call_by_reference, bool $prepare_output = true) //missing typehint because mixed
47  {
48  global $DIC;
49  $this->dic = $DIC;
50  $this->lng = $DIC->language();
51  $this->ctrl = $DIC->ctrl();
52  $this->tpl = $DIC["tpl"];
53 
54  $this->lng->loadLanguageModule("content");
55  $this->lng->loadLanguageModule("search");
56 
57  $this->refId = $DIC->http()->wrapper()->query()->retrieve('ref_id', $DIC->refinery()->kindlyTo()->int());
58 
59  $this->type = "sahs";
60  parent::__construct($data, $id, $call_by_reference, false);
61  }
62 
66  protected function assignObject(): void
67  {
68  if ($this->id != 0) {
69  if ($this->call_by_reference) {
70  $this->object = new ilObjSCORMLearningModule((int) $this->id, true);
71  } else {
72  $this->object = new ilObjSCORMLearningModule((int) $this->id, false);
73  }
74  }
75  }
76 
80  public function properties(): void
81  {
82  global $DIC;
83  $ilToolbar = $DIC->toolbar();
84  $ilTabs = $DIC->tabs();
85 
86  // $lng->loadLanguageModule("style");
87 
88  $this->setSettingsSubTabs();
89  $ilTabs->setSubTabActive('general');//cont_settings
90 
91  // view
92  $ilToolbar->addButtonInstance($this->object->getViewButton());
93  // $ilToolbar->addComponent($this->object->getViewButton());
94 
95  // lm properties
96  $this->initPropertiesForm();
97  $this->getPropertiesFormValues();
98  $this->tpl->setContent($this->form->getHTML());
99  }
100 
104  public function initPropertiesForm(): void
105  {
106  $obj_service = $this->object_service;
107  $this->form = new ilPropertyFormGUI();
108  $this->form->setTitle($this->lng->txt("cont_lm_properties"));
109 
110  //check/select only once
111  $this->object->checkMasteryScoreValues();
112 
113  //title
114  $ti = new ilTextInputGUI($this->lng->txt("title"), "Fobject_title");
115  $ti->setMaxLength(200);
116  $this->form->addItem($ti);
117 
118  //description
119  $ti = new ilTextAreaInputGUI($this->lng->txt("description"), "Fobject_description");
120  $ti->setCols(40);
121  $ti->setRows(2);
122  $this->form->addItem($ti);
123 
124  // SCORM-type
125  $ne = new ilNonEditableValueGUI($this->lng->txt("type"), "");
126  $ne->setValue($this->lng->txt("lm_type_" . ilObjSAHSLearningModule::_lookupSubType($this->object->getID())));
127  $this->form->addItem($ne);
128 
129  // version
130  $ne = new ilNonEditableValueGUI($this->lng->txt("cont_sc_version"), "");
131  $ne->setValue($this->object->getModuleVersion());
132  $ne->setInfo($this->lng->txt("cont_sc_version_info"));
133  $this->form->addItem($ne);
134 
135  //
136  // activation
137  //
138  $sh = new ilFormSectionHeaderGUI();
139  $sh->setTitle($this->lng->txt("activation"));
140  $this->form->addItem($sh);
141 
142  // online
143  $cb = new ilCheckboxInputGUI($this->lng->txt("cont_online"), "cobj_online");
144  $cb->setInfo($this->lng->txt("cont_online_info"));
145  $this->form->addItem($cb);
146 
147 
148  //
149  // presentation
150  //
151  $sh = new ilFormSectionHeaderGUI();
152  $sh->setTitle($this->lng->txt("cont_presentation"));
153  $this->form->addItem($sh);
154 
155  $radg = new ilRadioGroupInputGUI($this->lng->txt("cont_open"), "open_mode");
156  $op0 = new ilRadioOption($this->lng->txt("cont_open_normal"), "0");
157  $op0->setInfo($this->lng->txt("cont_open_normal_info"));
158  $radg->addOption($op0);
159  $op1 = new ilRadioOption($this->lng->txt("cont_open_iframe"), "1");
160  $op1->setInfo($this->lng->txt("cont_open_iframe_info"));
161  $radg->addOption($op1);
162  $op2 = new ilRadioOption($this->lng->txt("cont_open_window"), "5");
163  $op2->setInfo($this->lng->txt("cont_open_window_info"));
164  $radg->addOption($op2);
165 
166  // width
167  $ni = new ilNumberInputGUI($this->lng->txt("cont_width"), "width_0");
168  $ni->setMaxLength(4);
169  $ni->setSize(4);
170  $op1->addSubItem($ni);
171  $ni = new ilNumberInputGUI($this->lng->txt("cont_width"), "width_1");
172  $ni->setMaxLength(4);
173  $ni->setSize(4);
174  $op2->addSubItem($ni);
175  // height
176  $ni = new ilNumberInputGUI($this->lng->txt("cont_height"), "height_0");
177  $ni->setMaxLength(4);
178  $ni->setSize(4);
179  $ni->setInfo($this->lng->txt("cont_width_height_info"));
180  $op1->addSubItem($ni);
181  $ni = new ilNumberInputGUI($this->lng->txt("cont_height"), "height_1");
182  $ni->setMaxLength(4);
183  $ni->setSize(4);
184  $ni->setInfo($this->lng->txt("cont_width_height_info"));
185  $op2->addSubItem($ni);
186 
187  $this->form->addItem($radg);
188 
189  // auto navigation to last visited item
190  $cb = new ilCheckboxInputGUI($this->lng->txt("cont_auto_last_visited"), "cobj_auto_last_visited");
191  $cb->setValue("y");
192  $cb->setInfo($this->lng->txt("cont_auto_last_visited_info"));
193  $this->form->addItem($cb);
194 
195  // auto continue
196  $cb = new ilCheckboxInputGUI($this->lng->txt("cont_sc_auto_continue"), "auto_continue");
197  $cb->setValue("y");
198  $cb->setInfo($this->lng->txt("cont_sc_auto_continue_info"));
199  $this->form->addItem($cb);
200 
201  // tile image
202  $obj_service->commonSettings()->legacyForm($this->form, $this->object)->addTileImage();
203 
204  //
205  // scorm options
206  //
207  $sh = new ilFormSectionHeaderGUI();
208  $sh->setTitle($this->lng->txt("cont_scorm_options"));
209  $this->form->addItem($sh);
210 
211  // lesson mode
212  $radg = new ilRadioGroupInputGUI($this->lng->txt("cont_def_lesson_mode"), "lesson_mode");
213  $op0 = new ilRadioOption($this->lng->txt("cont_sc_less_mode_normal"), "normal");
214  $op0->setInfo($this->lng->txt("cont_sc_less_mode_normal_info"));
215  $radg->addOption($op0);
216  $op1 = new ilRadioOption($this->lng->txt("cont_sc_less_mode_browse"), "browse");
217  $op1->setInfo($this->lng->txt("cont_sc_less_mode_browse_info"));
218  $radg->addOption($op1);
219 
220 
221  // set lesson mode review when completed
222  $options = array(
223  "n" => $this->lng->txt("cont_sc_auto_review_no"),
224  "y" => $this->lng->txt("cont_sc_auto_review_completed_or_passed"),
225  );
226  $si = new ilSelectInputGUI($this->lng->txt("cont_sc_auto_review_2004"), "auto_review");
227  $si->setOptions($options);
228  // $si->setInfo($this->lng->txt("cont_sc_auto_review_info_12"));
229  $op0->addSubItem($si);
230  // end lesson mode
231  $this->form->addItem($radg);
232 
233  // mastery_score
234  if ($this->object->getMasteryScoreValues() != "") {
235  $ni = new ilNumberInputGUI($this->lng->txt("cont_mastery_score_12"), "mastery_score");
236  $ni->setMaxLength(3);
237  $ni->setSize(3);
238  $ni->setInfo($this->lng->txt("cont_mastery_score_12_info") . ' ' . $this->object->getMasteryScoreValues());
239  $this->form->addItem($ni);
240  }
241 
242  //
243  // rte settings
244  //
245  $sh = new ilFormSectionHeaderGUI();
246  $sh->setTitle($this->lng->txt("cont_rte_settings"));
247  $this->form->addItem($sh);
248 
249  // unlimited session timeout
250  $cb = new ilCheckboxInputGUI($this->lng->txt("cont_sc_usession"), "cobj_session");
251  $cb->setValue("y");
252  $cb->setInfo($this->lng->txt("cont_sc_usession_info"));
253  $this->form->addItem($cb);
254 
255  // storage of interactions
256  $cb = new ilCheckboxInputGUI($this->lng->txt("cont_interactions"), "cobj_interactions");
257  $cb->setValue("y");
258  $cb->setInfo($this->lng->txt("cont_interactions_info_12"));
259  $this->form->addItem($cb);
260 
261  // objectives
262  $cb = new ilCheckboxInputGUI($this->lng->txt("cont_objectives"), "cobj_objectives");
263  $cb->setValue("y");
264  $cb->setInfo($this->lng->txt("cont_objectives_info"));
265  $this->form->addItem($cb);
266 
267  // time from lms
268  $cb = new ilCheckboxInputGUI($this->lng->txt("cont_time_from_lms"), "cobj_time_from_lms");
269  $cb->setValue("y");
270  $cb->setInfo($this->lng->txt("cont_time_from_lms_info"));
271  $this->form->addItem($cb);
272 
273  // check values
274  $cb = new ilCheckboxInputGUI($this->lng->txt("cont_check_values"), "cobj_check_values");
275  $cb->setValue("y");
276  $cb->setInfo($this->lng->txt("cont_check_values_info"));
277  $this->form->addItem($cb);
278 
279  // auto cmi.core.exit to suspend
280  $cb = new ilCheckboxInputGUI($this->lng->txt("cont_auto_suspend"), "cobj_auto_suspend");
281  $cb->setValue("y");
282  $cb->setInfo($this->lng->txt("cont_auto_suspend_info"));
283  $this->form->addItem($cb);
284 
285  // settings for student_id
286  $options = array(
287  0 => $this->lng->txt("cont_sc_id_setting_user_id"),
288  1 => $this->lng->txt("cont_sc_id_setting_user_login"),
289  2 => $this->lng->txt("cont_sc_id_setting_user_id_plus_ref_id"),
290  3 => $this->lng->txt("cont_sc_id_setting_user_login_plus_ref_id"),
291  4 => $this->lng->txt("cont_sc_id_setting_user_id_plus_obj_id"),
292  5 => $this->lng->txt("cont_sc_id_setting_user_login_plus_obj_id")
293  );
294  $si = new ilSelectInputGUI($this->lng->txt("cont_sc_id_setting"), "id_setting");
295  $si->setOptions($options);
296  $si->setInfo($this->lng->txt("cont_sc_id_setting_info"));
297  $this->form->addItem($si);
298 
299  // settings for student_name
300  $options = array(
301  0 => $this->lng->txt("cont_sc_name_setting_last_firstname"),
302  1 => $this->lng->txt("cont_sc_name_setting_first_lastname"),
303  2 => $this->lng->txt("cont_sc_name_setting_fullname"),
304  3 => $this->lng->txt("cont_sc_name_setting_salutation_lastname"),
305  4 => $this->lng->txt("cont_sc_name_setting_first_name"),
306  9 => $this->lng->txt("cont_sc_name_setting_no_name")
307  );
308  $si = new ilSelectInputGUI($this->lng->txt("cont_sc_name_setting"), "name_setting");
309  $si->setOptions($options);
310  $si->setInfo($this->lng->txt("cont_sc_name_setting_info"));
311  $this->form->addItem($si);
312 
313  //
314  // debugging
315  //
316  $sh = new ilFormSectionHeaderGUI();
317  $sh->setTitle($this->lng->txt("cont_debugging"));
318  $this->form->addItem($sh);
319 
320  // test tool
321  $cb = new ilCheckboxInputGUI($this->lng->txt("cont_debug"), "cobj_debug");
322  $cb->setValue("y");
323  if ($this->object->getDebugActivated() == false) {
324  $cb->setDisabled(true);
325  $cb->setInfo($this->lng->txt("cont_debug_deactivated"));
326  } else {
327  $cb->setInfo($this->lng->txt("cont_debug_deactivate12"));
328  }
329  $this->form->addItem($cb);
330  $this->form->addCommandButton("saveProperties", $this->lng->txt("save"));
331  $this->form->setFormAction($this->ctrl->getFormAction($this));
332  }
333 
334 
338  public function getPropertiesFormValues(): void
339  {
340  $values = array();
341  $values["Fobject_title"] = $this->object->getTitle();
342  $values["Fobject_description"] = $this->object->getLongDescription();
343  if (!$this->object->getOfflineStatus()) {
344  $values["cobj_online"] = true;
345  }
346  // $values["cobj_offline_mode"] = $this->object->getOfflineMode();
347  $values["open_mode"] = $this->object->getOpenMode();
348  $values["width_0"] = $this->object->getWidth();
349  $values["width_1"] = $this->object->getWidth();
350  $values["height_0"] = $this->object->getHeight();
351  $values["height_1"] = $this->object->getHeight();
352  $values["cobj_auto_last_visited"] = $this->object->getAuto_last_visited();
353  $values["auto_continue"] = $this->object->getAutoContinue();
354  $values["lesson_mode"] = $this->object->getDefaultLessonMode();
355  $values["auto_review"] = $this->object->getAutoReviewChar();
356  $values["mastery_score"] = $this->object->getMasteryScore();
357  $values["cobj_session"] = $this->object->getSession();
358  $values["cobj_interactions"] = $this->object->getInteractions();
359  $values["cobj_objectives"] = $this->object->getObjectives();
360  $values["cobj_time_from_lms"] = $this->object->getTime_from_lms();
361  $values["cobj_check_values"] = $this->object->getCheck_values();
362  $values["cobj_auto_suspend"] = $this->object->getAutoSuspend();
363  $values["id_setting"] = $this->object->getIdSetting();
364  $values["name_setting"] = $this->object->getNameSetting();
365  $values["cobj_debug"] = $this->object->getDebug();
366  $this->form->setValuesByArray($values);
367  }
368 
372  public function newModuleVersion(): void
373  {
374  global $DIC;
375  $ilTabs = $DIC->tabs();
376  $this->setSettingsSubTabs();
377  $ilTabs->setSubTabActive('cont_sc_new_version');
378 
379  $obj_id = ilObject::_lookupObjectId($this->refId);
381  $this->form = new ilPropertyFormGUI();
382  //title
383  $this->form->setTitle($this->lng->txt("import_sahs_new"));
384 
385  $this->form->setDescription($this->lng->txt("import_sahs_info"));
386 
387  // SCORM-type
388  $ne = new ilNonEditableValueGUI($this->lng->txt("type"), "");
389  $ne->setValue($this->lng->txt("lm_type_" . ilObjSAHSLearningModule::_lookupSubType($this->object->getID())));
390  $this->form->addItem($ne);
391 
392  $options = array();
394  $options[""] = $this->lng->txt("cont_select_from_upload_dir");
396  foreach ($files as $file) {
397  $file = htmlspecialchars($file, ENT_QUOTES, "utf-8");
398  $options[$file] = $file;
399  }
400  }
401  if (count($options) > 1) {
402  // choose upload directory
403  $radg = new ilRadioGroupInputGUI($this->lng->txt("cont_choose_file_source"), "file_source");
404  $op0 = new ilRadioOption($this->lng->txt("cont_choose_local"), "local");
405  $radg->addOption($op0);
406  $op1 = new ilRadioOption($this->lng->txt("cont_choose_upload_dir"), "upload_dir");
407  $radg->addOption($op1);
408  $radg->setValue("local");
409 
410  $fi = new ilFileInputGUI($this->lng->txt("select_file"), "scormfile");
411  $fi->setRequired(true);
412  $op0->addSubItem($fi);
413 
414  $si = new ilSelectInputGUI($this->lng->txt("cont_uploaded_file"), "uploaded_file");
415  $si->setOptions($options);
416  $op1->addSubItem($si);
417 
418  $this->form->addItem($radg);
419  } else {
420  $fi = new ilFileInputGUI($this->lng->txt("select_file"), "scormfile");
421  $fi->setRequired(true);
422  $this->form->addItem($fi);
423  }
424  $this->form->addCommandButton("newModuleVersionUpload", $this->lng->txt("upload"));
425  $this->form->addCommandButton("cancel", $this->lng->txt("cancel"));
426  $this->form->setFormAction($DIC->ctrl()->getFormAction($this, "newModuleVersionUpload"));
427  $DIC['tpl']->setContent($this->form->getHTML());
428  }
429 
430  public function getMaxFileSize(): string
431  {
432  // get the value for the maximal uploadable filesize from the php.ini (if available)
433  $umf = get_cfg_var("upload_max_filesize");
434  // get the value for the maximal post data from the php.ini (if available)
435  $pms = get_cfg_var("post_max_size");
436 
437  //convert from short-string representation to "real" bytes
438  $multiplier_a = array("K" => 1024, "M" => 1024 * 1024, "G" => 1024 * 1024 * 1024);
439 
440  $umf_parts = preg_split("/(\d+)([K|G|M])/", $umf, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
441  $pms_parts = preg_split("/(\d+)([K|G|M])/", $pms, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
442 
443  if (count($umf_parts) == 2) {
444  $umf = $umf_parts[0] * $multiplier_a[$umf_parts[1]];
445  }
446  if (count($pms_parts) == 2) {
447  $pms = $pms_parts[0] * $multiplier_a[$pms_parts[1]];
448  }
449 
450  // use the smaller one as limit
451  $max_filesize = min($umf, $pms);
452 
453  if (!$max_filesize) {
454  $max_filesize = max($umf, $pms);
455  }
456 
457  //format for display in mega-bytes
458  return $max_filesize = sprintf("%.1f MB", $max_filesize / 1024 / 1024);
459  }
460 
465  public function newModuleVersionUpload(): void
466  {
467  global $DIC;
468  $rbacsystem = $DIC->access();
469  $ilErr = $DIC["ilErr"];
470 
471  $unzip = PATH_TO_UNZIP;
472  $tocheck = "imsmanifest.xml";
473 
474  // check create permission before because the uploaded file will be copied
475  if (!$rbacsystem->checkAccess("write", "", $this->refId)) {
476  $ilErr->raiseError($this->lng->txt("no_create_permission"), $ilErr->WARNING);
477  } elseif ($_FILES["scormfile"]["name"]) {
478  // check if file was uploaded
479  $source = $_FILES["scormfile"]["tmp_name"];
480  if (($source === 'none') || (!$source)) {
481  $this->tpl->setOnScreenMessage('info', $this->lng->txt("upload_error_file_not_found"), true);
482  $this->newModuleVersion();
483  return;
484  }
485  } elseif ($DIC->http()->wrapper()->post()->has('uploaded_file')) {
486  $uploadedFile = $DIC->http()->wrapper()->post()->retrieve('uploaded_file', $DIC->refinery()->kindlyTo()->string());
487  // check if the file is in the ftp directory and readable
488  if (!ilUploadFiles::_checkUploadFile($uploadedFile)) {
489  $ilErr->raiseError($this->lng->txt("upload_error_file_not_found"), $ilErr->MESSAGE);
490  }
491  // copy the uploaded file to the client web dir to analyze the imsmanifest
492  // the copy will be moved to the lm directory or deleted
493  $source = CLIENT_WEB_DIR . "/" . $uploadedFile;
494  ilUploadFiles::_copyUploadFile($uploadedFile, $source);
495  $source_is_copy = true;
496  } else {
497  $this->tpl->setOnScreenMessage('info', $this->lng->txt("upload_error_file_not_found"), true);
498  $this->newModuleVersion();
499  return;
500  }
501  // fim.
502 
503  //unzip the imsmanifest-file from new uploaded file
504  $pathinfo = pathinfo($source);
505  $dir = $pathinfo["dirname"];
506  $file = $pathinfo["basename"];
507  $cdir = getcwd();
508  chdir($dir);
509 
510  //we need more flexible unzip here than ILIAS standard classes allow
511  $unzipcmd = $unzip . " -o " . ilShellUtil::escapeShellArg($source) . " " . $tocheck;
512  exec($unzipcmd);
513  chdir($cdir);
514  $tmp_file = $dir . "/" . $this->refId . "." . $tocheck;
515 
516  ilFileUtils::rename($dir . "/" . $tocheck, $tmp_file);
517  $new_manifest = file_get_contents($tmp_file);
518 
519  //remove temp file
520  unlink($tmp_file);
521 
522  //get old manifest file
523  $old_manifest = file_get_contents($this->object->getDataDirectory() . "/" . $tocheck);
524 
525  //reload fixed version of file
526  $check = '/xmlns="http:\/\/www.imsglobal.org\/xsd\/imscp_v1p1"/';
527  $replace = "xmlns=\"http://www.imsproject.org/xsd/imscp_rootv1p1p2\"";
528  $reload_manifest = preg_replace($check, $replace, $new_manifest);
529 
530  //do testing for converted versions as well as earlier ILIAS version messed up utf8 conversion
531  if (strcmp($new_manifest, $old_manifest) == 0 || strcmp(mb_convert_encoding($new_manifest, "UTF-8", mb_detect_encoding($new_manifest)), $old_manifest) == 0 ||
532  strcmp($reload_manifest, $old_manifest) == 0 || strcmp(mb_convert_encoding($reload_manifest, "UTF-8", mb_detect_encoding($reload_manifest)), $old_manifest) == 0) {
533 
534  //get exisiting module version
535  $module_version = $this->object->getModuleVersion() + 1;
536 
537  if ($_FILES["scormfile"]["name"]) {
538  //build targetdir in lm_data
539  $file_path = $this->object->getDataDirectory() . "/" . $_FILES["scormfile"]["name"] . "." . $module_version;
540  $file_path = str_replace(".zip." . $module_version, "." . $module_version . ".zip", $file_path);
541  //move to data directory and add subfix for versioning
543  $_FILES["scormfile"]["tmp_name"],
544  $_FILES["scormfile"]["name"],
545  $file_path
546  );
547  } else {
548  //build targetdir in lm_data
549  $uploadedFile = $DIC->http()->wrapper()->post()->retrieve('uploaded_file', $DIC->refinery()->kindlyTo()->string());
550  $file_path = $this->object->getDataDirectory() . "/" . $uploadedFile . "." . $module_version;
551  $file_path = str_replace(".zip." . $module_version, "." . $module_version . ".zip", $file_path);
552  // move the already copied file to the lm_data directory
553  ilFileUtils::rename($source, $file_path);
554  }
555 
556  //unzip and replace old extracted files
557  $DIC->legacyArchives()->unzip($file_path, null, true);
558  ilFileUtils::renameExecutables($this->object->getDataDirectory()); //(security)
559 
560  //increase module version
561  $this->object->setModuleVersion($module_version);
562  $this->object->update();
563 
564  //redirect to properties and display success
565  $this->tpl->setOnScreenMessage('info', $this->lng->txt("cont_new_module_added"), true);
566  ilUtil::redirect("ilias.php?baseClass=ilSAHSEditGUI&ref_id=" . $this->refId);
567  exit;
568  }
569 
570  if (isset($source_is_copy)) {
571  unlink($source);
572  }
573 
574  $this->tpl->setOnScreenMessage('info', $this->lng->txt("cont_invalid_new_module"), true);
575  $this->newModuleVersion();
576  }
577 
581  public function saveProperties(): void
582  {
583  $obj_service = $this->object_service;
584  $this->initPropertiesForm();
585  if ($this->form->checkInput()) {
586  $this->object->setTitle($this->dic->http()->wrapper()->post()->retrieve('Fobject_title', $this->dic->refinery()->kindlyTo()->string()));
587  $this->object->setDescription($this->dic->http()->wrapper()->post()->retrieve('Fobject_description', $this->dic->refinery()->kindlyTo()->string()));
588 
589  if ($this->dic->http()->wrapper()->post()->has('mastery_score')) {
590  $sMasteryScore = $this->dic->http()->wrapper()->post()->retrieve('mastery_score', $this->dic->refinery()->kindlyTo()->string());
591  if ($sMasteryScore !== "") {
592  $this->object->setMasteryScore((int) $sMasteryScore);
593  } else {
594  $this->object->setMasteryScore(null);
595  }
596  }
597 
598  $t_height = $this->object->getHeight();
599  if ($this->dic->http()->wrapper()->post()->retrieve('height_0', $this->dic->refinery()->kindlyTo()->int()) != $this->object->getHeight()) {
600  $t_height = $this->dic->http()->wrapper()->post()->retrieve('height_0', $this->dic->refinery()->kindlyTo()->int());
601  }
602  if ($this->dic->http()->wrapper()->post()->retrieve('height_1', $this->dic->refinery()->kindlyTo()->int()) != $this->object->getHeight()) {
603  $t_height = $this->dic->http()->wrapper()->post()->retrieve('height_1', $this->dic->refinery()->kindlyTo()->int());
604  }
605 
606  $t_width = $this->object->getWidth();
607  if ($this->dic->http()->wrapper()->post()->retrieve('width_0', $this->dic->refinery()->kindlyTo()->int()) != $this->object->getWidth()) {
608  $t_width = $this->dic->http()->wrapper()->post()->retrieve('width_0', $this->dic->refinery()->kindlyTo()->int());
609  }
610  if ($this->dic->http()->wrapper()->post()->retrieve('width_1', $this->dic->refinery()->kindlyTo()->int()) != $this->object->getWidth()) {
611  $t_width = $this->dic->http()->wrapper()->post()->retrieve('width_1', $this->dic->refinery()->kindlyTo()->int());
612  }
613 
614  $this->object->setOfflineStatus(!($this->dic->http()->wrapper()->post()->has('cobj_online')));
615  // $this->object->setOfflineMode($tmpOfflineMode);
616  $this->object->setOpenMode($this->dic->http()->wrapper()->post()->retrieve('open_mode', $this->dic->refinery()->kindlyTo()->int()));
617  $this->object->setWidth($t_width);
618  $this->object->setHeight($t_height);
619  $this->object->setAuto_last_visited($this->dic->http()->wrapper()->post()->has('cobj_auto_last_visited'));
620  $this->object->setAutoContinue($this->dic->http()->wrapper()->post()->has('auto_continue'));
621  // $this->object->setMaxAttempt((int) $_POST["max_attempt"]);
622  $this->object->setDefaultLessonMode($this->dic->http()->wrapper()->post()->retrieve('lesson_mode', $this->dic->refinery()->kindlyTo()->string()));
623  $this->object->setAutoReview(ilUtil::yn2tf($this->dic->http()->wrapper()->post()->retrieve('auto_review', $this->dic->refinery()->kindlyTo()->string())));
624  $this->object->setSession($this->dic->http()->wrapper()->post()->has('cobj_session'));
625  $this->object->setInteractions($this->dic->http()->wrapper()->post()->has('cobj_interactions'));
626  $this->object->setObjectives($this->dic->http()->wrapper()->post()->has('cobj_objectives'));
627  $this->object->setTime_from_lms($this->dic->http()->wrapper()->post()->has('cobj_time_from_lms'));
628  $this->object->setCheck_values($this->dic->http()->wrapper()->post()->has('cobj_check_values'));
629  $this->object->setAutoSuspend($this->dic->http()->wrapper()->post()->has('cobj_auto_suspend'));
630  $this->object->setDebug($this->dic->http()->wrapper()->post()->has('cobj_debug'));
631  $this->object->setIdSetting($this->dic->http()->wrapper()->post()->retrieve('id_setting', $this->dic->refinery()->kindlyTo()->int()));
632  $this->object->setNameSetting($this->dic->http()->wrapper()->post()->retrieve('name_setting', $this->dic->refinery()->kindlyTo()->int()));
633  $this->object->update();
634 
635  // tile image
636  $obj_service->commonSettings()->legacyForm($this->form, $this->object)->saveTileImage();
637  }
638  $this->tpl->setOnScreenMessage('info', $this->lng->txt("msg_obj_modified"), true);
639  $this->ctrl->redirect($this, "properties");
640  }
641 
645  protected function showTrackingItemsBySco(): bool
646  {
647  global $DIC;
648  $ilTabs = $DIC->tabs();
649 
650  $this->setSubTabs();
651  $ilTabs->setTabActive("cont_tracking_data");
652  $ilTabs->setSubTabActive("cont_tracking_bysco");
653 
654  $reports = array('exportSelectedCore','exportSelectedInteractions','exportSelectedObjectives','exportSelectedRaw');//,'tracInteractionItem','tracInteractionUser','tracInteractionUserAnswers'
655  $scoSelected = "all";
656  if ($this->dic->http()->wrapper()->query()->has('scoSelected')) {
657  $scoSelected = ilUtil::stripSlashes($this->dic->http()->wrapper()->query()->retrieve('scoSelected', $this->dic->refinery()->kindlyTo()->string()));
658  }
659  if ($this->dic->http()->wrapper()->post()->has('scoSelected')) {
660  $scoSelected = ilUtil::stripSlashes($this->dic->http()->wrapper()->post()->retrieve('scoSelected', $this->dic->refinery()->kindlyTo()->string()));
661  }
662  $this->ctrl->setParameter($this, 'scoSelected', $scoSelected);
663 
664  $report = "choose";
665  if ($this->dic->http()->wrapper()->query()->has('report')) {
666  $report = ilUtil::stripSlashes($this->dic->http()->wrapper()->query()->retrieve('report', $this->dic->refinery()->kindlyTo()->string()));
667  }
668  if ($this->dic->http()->wrapper()->post()->has('report')) {
669  $report = ilUtil::stripSlashes($this->dic->http()->wrapper()->post()->retrieve('report', $this->dic->refinery()->kindlyTo()->string()));
670  }
671  $this->ctrl->setParameter($this, 'report', $report);
672  $filter = new ilSCORMTrackingItemsPerScoFilterGUI($this, 'showTrackingItemsBySco');
673  $filter->parse($scoSelected, $report, $reports);
674  if ($report === "choose") {
675  $this->tpl->setContent($filter->form->getHTML());
676  } else {
677  $scosSelected = array();
678  if ($scoSelected !== "all") {
679  $scosSelected[] = $scoSelected;
680  } else {
681  $scos = $this->object->getTrackedItems();
682  foreach ($scos as $row) {
683  $scosSelected[] = (int) $row->getId();
684  }
685  }
686  $a_users = ilTrQuery::getParticipantsForObject($this->ref_id);
687  $tbl = new ilSCORMTrackingItemsTableGUI($this->object->getId(), $this, 'showTrackingItemsBySco', $a_users, $scosSelected, $report);
688  $this->tpl->setContent($filter->form->getHTML() . $tbl->getHTML());
689  }
690  return true;
691  }
692 
697  public function showTrackingItems(): bool
698  {
699  global $DIC;
700  $ilTabs = $DIC->tabs();
701  $ilAccess = $DIC->access();
702 
703  $ilTabs->setTabActive('cont_tracking_data');
704 
705  if ($ilAccess->checkAccess("read_learning_progress", "", $this->refId)) {
706  $this->setSubTabs();
707  $ilTabs->setSubTabActive('cont_tracking_byuser');
708 
709  $reports = array('exportSelectedSuccess','exportSelectedCore','exportSelectedInteractions','exportSelectedObjectives','exportSelectedRaw');
710 
711  $userSelected = "all";
712  if ($this->dic->http()->wrapper()->query()->has('userSelected')) {
713  $userSelected = ilUtil::stripSlashes($this->dic->http()->wrapper()->query()->retrieve('userSelected', $this->dic->refinery()->kindlyTo()->string()));
714  }
715  if ($this->dic->http()->wrapper()->post()->has('userSelected')) {
716  $userSelected = ilUtil::stripSlashes($this->dic->http()->wrapper()->post()->retrieve('userSelected', $this->dic->refinery()->kindlyTo()->string()));
717  }
718  $this->ctrl->setParameter($this, 'userSelected', $userSelected);
719 
720  $report = "choose";
721  if ($this->dic->http()->wrapper()->query()->has('report')) {
722  $report = ilUtil::stripSlashes($this->dic->http()->wrapper()->query()->retrieve('report', $this->dic->refinery()->kindlyTo()->string()));
723  }
724  if ($this->dic->http()->wrapper()->post()->has('report')) {
725  $report = ilUtil::stripSlashes($this->dic->http()->wrapper()->post()->retrieve('report', $this->dic->refinery()->kindlyTo()->string()));
726  }
727  $this->ctrl->setParameter($this, 'report', $report);
728  $filter = new ilSCORMTrackingItemsPerUserFilterGUI($this, 'showTrackingItems');
729  $filter->parse($userSelected, $report, $reports);
730  if ($report === "choose") {
731  $this->tpl->setContent($filter->form->getHTML());
732  } else {
733  $usersSelected = array();
734  if ($userSelected !== "all") {
735  $usersSelected[] = $userSelected;
736  } else {
737  $users = ilTrQuery::getParticipantsForObject($this->ref_id);
738  foreach ($users as $user) {
739  if (ilObject::_exists((int) $user) && ilObject::_lookUpType((int) $user) === 'usr') {
740  $usersSelected[] = (int) $user;
741  }
742  }
743  }
744  $scosSelected = array();
745  $scos = $this->object->getTrackedItems();
746  foreach ($scos as $row) {
747  $scosSelected[] = (int) $row->getId();
748  }
749  $tbl = new ilSCORMTrackingItemsTableGUI($this->object->getId(), $this, 'showTrackingItems', $usersSelected, $scosSelected, $report);
750  $this->tpl->setContent($filter->form->getHTML() . $tbl->getHTML());
751  }
752  } elseif ($ilAccess->checkAccess("edit_learning_progress", "", $this->refId)) {
753  $this->modifyTrackingItems();
754  }
755  return true;
756  }
757 
761  protected function modifyTrackingItems(): void
762  {
763  global $DIC;
764  $ilAccess = $DIC->access();
765  $ilErr = $DIC["ilErr"];
766  if ($ilAccess->checkAccess("edit_learning_progress", "", $this->refId)) {
767  $privacy = ilPrivacySettings::getInstance();
768  if (!$privacy->enabledSahsProtocolData()) {
769  $ilErr->raiseError($this->lng->txt('permission_denied'), $ilErr->MESSAGE);
770  }
771 
772  global $DIC;
773  $ilTabs = $DIC->tabs();
774  $ilToolbar = $DIC->toolbar();
775  $ilToolbar->addButton(
776  $this->lng->txt('import'),
777  $this->ctrl->getLinkTarget($this, 'trackingImportForm')
778  );
779  $ilToolbar->addButton(
780  $this->lng->txt('cont_export_all'),
781  $this->ctrl->getLinkTarget($this, 'exportAll')
782  );
783 
784  $this->setSubTabs();
785  $ilTabs->setTabActive('cont_tracking_data');
786  $ilTabs->setSubTabActive('cont_tracking_modify');
787  $tbl = new ilSCORMTrackingUsersTableGUI($this->object->getId(), $this, 'modifytrackingItems');
788  $tbl->parse();
789  $this->tpl->setContent($tbl->getHTML());
790  }
791  }
792 
796  protected function applyUserTableFilter(): void
797  {
798  $tbl = new ilSCORMTrackingUsersTableGUI($this->object->getId(), $this, 'modifytrackingItems');
799  $tbl->writeFilterToSession();
800  $tbl->resetOffset();
801  $this->modifyTrackingItems();
802  }
803 
808  protected function resetUserTableFilter(): void
809  {
810  $tbl = new ilSCORMTrackingUsersTableGUI($this->object->getId(), $this, 'modifytrackingItems');
811  $tbl->resetFilter();
812  $tbl->resetOffset();
813  $this->modifyTrackingItems();
814  }
815 
820  public function deleteTrackingForUser(): void
821  {
822  global $DIC;
823  $ilErr = $DIC["ilErr"];
824 
825  if (!$DIC->http()->wrapper()->post()->has('user')) {
826  $ilErr->raiseError($this->lng->txt("no_checkbox"), $ilErr->MESSAGE);
827  }
828 
829  // display confirmation message
830  $cgui = new ilConfirmationGUI();
831  $cgui->setFormAction($this->ctrl->getFormAction($this));
832  $cgui->setHeaderText($this->lng->txt("info_delete_sure"));
833  $cgui->setCancel($this->lng->txt("cancel"), "cancelDeleteTracking");
834  $cgui->setConfirm($this->lng->txt("confirm"), "confirmedDeleteTracking");
835  foreach ($DIC->http()->wrapper()->post()->retrieve('user', $DIC->refinery()->kindlyTo()->listOf($DIC->refinery()->kindlyTo()->int())) as $id) {
836  if (ilObject::_exists((int) $id) && ilObject::_lookUpType((int) $id) === "usr") {
837  $user = new ilObjUser((int) $id);
838 
839  //was ilUtil::getImageTagByType("sahs", (string) $this->tpl->getValue("TPLPATH")) .
840  $caption = $this->lng->txt("cont_tracking_data") . ": " . $user->getLastname() . ", " . $user->getFirstname();
841 
842  $cgui->addItem("user[]", (string) $id, $caption);
843  }
844  }
845 
846  $this->tpl->setContent($cgui->getHTML());
847  }
848 
853  public function cancelDeleteTracking(): void
854  {
855  $this->tpl->setOnScreenMessage('info', $this->lng->txt("msg_cancel"), true);
856  $this->ctrl->redirect($this, "modifyTrackingItems");
857  }
858 
862  public function confirmedDeleteTracking(): void
863  {
864  $this->object->deleteTrackingDataOfUsers($this->post_wrapper->retrieve('user', $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())));
865  $this->ctrl->redirect($this, "modifyTrackingItems");
866  }
867 
872  public function cancel(): void
873  {
874  $this->tpl->setOnScreenMessage('info', $this->lng->txt("msg_cancel"), true);
875  $this->ctrl->redirect($this, "properties");
876  }
877 
882  protected function importTracking(): void
883  {
884  $form = $this->initTrackingImportForm("");
885  if ($form->checkInput()) {
886  $source = $form->getInput('csv');
887  $success = $this->object->importTrackingData($source['tmp_name']);
888  switch ($success) {
889  case true:
890  $this->tpl->setOnScreenMessage('info', 'Tracking data imported', true);
891  $this->ctrl->redirect($this, "showTrackingItems");
892  break;
893  case false:
894  $this->tpl->setOnScreenMessage('info', $this->lng->txt('err_check_input'));
895  $this->trackingImportForm();
896  break;
897  }
898  }
899  $this->tpl->setOnScreenMessage('info', $this->lng->txt('err_check_input'));
900  $form->setValuesByPost();
901  $this->trackingImportForm();
902  }
903 
908  protected function trackingImportForm(): void
909  {
910  global $DIC;
911  $ilTabs = $DIC->tabs();
912 
913  $ilTabs->clearTargets();
914  $ilTabs->setBackTarget($this->lng->txt('back'), $this->ctrl->getLinkTarget($this, 'showTrackingItems'));
915 
916  $form = $this->initTrackingImportForm();
917  $this->tpl->setContent($form->getHTML());
918  }
919 
925  {
926  $form = new ilPropertyFormGUI();
927  $form->setFormAction($this->ctrl->getFormAction($this));
928  $form->setTitle($this->lng->txt('cont_import_tracking'));
929  $form->addCommandButton('importTracking', $this->lng->txt('import'));
930  $form->addCommandButton('showTrackingItems', $this->lng->txt('cancel'));
931 
932  $csv = new ilFileInputGUI($this->lng->txt('select_file'), 'csv');
933  $csv->setRequired(true);
934  $csv->setSuffixes(array('csv'));
935  $form->addItem($csv);
936 
937  return $form;
938  }
939 
943  protected function exportAll(): void
944  {
945  $this->object->exportSelected(true);
946  }
947 
952  protected function exportSelectionUsers(): void
953  {
954  if (!$this->post_wrapper->has('user')) {
955  //was if (!count((array) $_POST['user'])) {
956  //ilUtil::sendFailure($this->lng->txt('select_one'),true);
957  $this->tpl->setOnScreenMessage('info', $this->lng->txt("no_checkbox"), true);
958  $this->ctrl->redirect($this, 'modifyTrackingItems');
959  } else {
960  $this->object->exportSelected(false, $this->post_wrapper->retrieve('user', $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())));
961  }
962  }
963 
964 
968  public function setSubTabs(): void
969  {
970  global $DIC;
971  $lng = $DIC->language();
972  $ilTabs = $DIC->tabs();
973  $ilCtrl = $DIC->ctrl();
974  $ilAccess = $DIC->access();
975 
976  if ($ilAccess->checkAccess("read_learning_progress", "", $this->refId)) {
977  $ilTabs->addSubTabTarget(
978  "cont_tracking_byuser",
979  $this->ctrl->getLinkTarget($this, "showTrackingItems"),
980  array("edit", ""),
981  get_class($this)
982  );
983 
984  $ilTabs->addSubTabTarget(
985  "cont_tracking_bysco",
986  $this->ctrl->getLinkTarget($this, "showTrackingItemsBySco"),
987  array("edit", ""),
988  get_class($this)
989  );
990  }
991  if ($ilAccess->checkAccess("edit_learning_progress", "", $this->refId)) {
992  $ilTabs->addSubTabTarget(
993  "cont_tracking_modify",
994  $this->ctrl->getLinkTarget($this, "modifyTrackingItems"),
995  array("edit", ""),
996  get_class($this)
997  );
998  }
999  }
1000 }
1001 // END class.ilObjSCORMLearningModule
Class ilSCORMTrackingItemsTableGUI.
This class represents an option in a radio group.
Class ilObjSCORMLearningModuleGUI.
exportAll()
Show export section for all users.
static _copyUploadFile(string $a_file, string $a_target, bool $a_raise_errors=true)
cancelDeleteTracking()
cancel deletion of export files
This class represents a selection list property in a property form.
This class represents a file property in a property form.
getPropertiesFormValues()
Get values for properties form.
setInfo(string $a_info)
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
setMaxLength(int $a_maxlength)
assignObject()
assign scorm object to scorm gui object
static _getUploadDirectory()
static escapeShellArg(string $a_arg)
setOptions(array $a_options)
getInput(string $a_post_var, bool $ensureValidation=true)
Returns the input of an item, if item provides getInput method and as fallback the value of the HTTP-...
static _lookupSubType(int $a_obj_id)
lookup subtype id (scorm, )
$ilErr
Definition: raiseError.php:33
exportSelectionUsers()
Export selection for selected users.
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static renameExecutables(string $a_dir)
ilLanguage $lng
deleteTrackingForUser()
display deletion confirmation screen
static _exists(int $id, bool $reference=false, ?string $type=null)
checks if an object exists in object_data
This class represents a property in a property form.
setFormAction(string $a_formaction)
This class represents a number property in a property form.
setValue(string $a_value)
global $DIC
Definition: shib_login.php:26
static _lookupObjectId(int $ref_id)
ilObjectService $object_service
const CLIENT_WEB_DIR
Definition: constants.php:47
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file
setRequired(bool $a_required)
importTracking()
gui functions for GUI export
addCommandButton(string $a_cmd, string $a_text, string $a_id="")
exit
newModuleVersion()
upload new version of module
static redirect(string $a_script)
form( $class_path, string $cmd, string $submit_caption="")
__construct(Container $dic, ilPlugin $plugin)
This class represents a text area property in a property form.
static getParticipantsForObject(int $a_ref_id)
Get participant ids for given object.
static _checkUploadFile(string $a_file)
$check
Definition: buildRTE.php:81
static yn2tf(string $a_yn)
static rename(string $a_source, string $a_target)
Class ilObjSCORMLearningModule.
cancel()
overwrite..jump back to trackingdata not parent
__construct($data, int $id, bool $call_by_reference, bool $prepare_output=true)
Constructor.