ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilObjSCORMLearningModuleGUI.php
Go to the documentation of this file.
1<?php
2
19declare(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";
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();
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)) {
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
$check
Definition: buildRTE.php:81
This class represents a checkbox property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilCtrl provides processing control methods.
This class represents a file property in a property form.
static rename(string $a_source, string $a_target)
static renameExecutables(string $a_dir)
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file
setFormAction(string $a_formaction)
This class represents a section header in a property form.
This class represents a non editable value in a property form.
This class represents a number property in a property form.
static _lookupSubType(int $a_obj_id)
lookup subtype id (scorm, )
Class ilObjSCORMLearningModuleGUI.
__construct($data, int $id, bool $call_by_reference, bool $prepare_output=true)
Constructor.
exportAll()
Show export section for all users.
exportSelectionUsers()
Export selection for selected users.
assignObject()
assign scorm object to scorm gui object
deleteTrackingForUser()
display deletion confirmation screen
cancel()
overwrite..jump back to trackingdata not parent
newModuleVersion()
upload new version of module
importTracking()
gui functions for GUI export
cancelDeleteTracking()
cancel deletion of export files
getPropertiesFormValues()
Get values for properties form.
Class ilObjSCORMLearningModule.
User class.
ilObjectService $object_service
ilLanguage $lng
static _lookupObjectId(int $ref_id)
static _exists(int $id, bool $reference=false, ?string $type=null)
checks if an object exists in object_data
This class represents a property form user interface.
addCommandButton(string $a_cmd, string $a_text, string $a_id="")
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-...
This class represents a property in a property form.
This class represents an option in a radio group.
Class ilSCORMTrackingItemsTableGUI.
This class represents a selection list property in a property form.
static escapeShellArg(string $a_arg)
This class represents a text area property in a property form.
This class represents a text property in a property form.
static getParticipantsForObject(int $a_ref_id)
Get participant ids for given object.
static _copyUploadFile(string $a_file, string $a_target, bool $a_raise_errors=true)
static _checkUploadFile(string $a_file)
static _getUploadDirectory()
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
static yn2tf(string $a_yn)
static redirect(string $a_script)
const CLIENT_WEB_DIR
Definition: constants.php:47
exit
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
form( $class_path, string $cmd, string $submit_caption="")
$ilErr
Definition: raiseError.php:33
global $DIC
Definition: shib_login.php:26
PREG_SPLIT_NO_EMPTY PREG_SPLIT_DELIM_CAPTURE