1<?php 2 3/* Copyright (c) 1998-2011 ILIAS open source, Extended GPL, see docs/LICENSE */ 4 5require_once "./Services/Object/classes/class.ilObject.php"; 6require_once "./Modules/ScormAicc/classes/class.ilObjSCORMValidator.php"; 7//require_once "Services/MetaData/classes/class.ilMDLanguageItem.php"; 8 9/** @defgroup ModulesScormAicc Modules/ScormAicc 10 */ 11 12/** 13* Class ilObjSCORMLearningModule 14* 15* @author Alex Killing <alex.killing@gmx.de> 16* $Id$ 17* 18* @ingroup ModulesScormAicc 19*/ 20class ilObjSAHSLearningModule extends ilObject 21{ 22 public $validator; 23 // var $meta_data; 24 25 /** 26 * Constructor 27 * @access public 28 * @param integer reference_id or object_id 29 * @param boolean treat the id as reference_id (true) or object_id (false) 30 */ 31 public function __construct($a_id = 0, $a_call_by_reference = true) 32 { 33 $this->type = "sahs"; 34 parent::__construct($a_id, $a_call_by_reference); 35 } 36 37 /** 38 * create file based lm 39 */ 40 public function create($upload = false) 41 { 42 global $DIC; 43 $ilDB = $DIC['ilDB']; 44 45 parent::create(); 46 if (!$upload) { 47 $this->createMetaData(); 48 } 49 50 $this->createDataDirectory(); 51 $ilDB->manipulateF( 52 ' 53 INSERT INTO sahs_lm (id, api_adapter, c_type, editable, seq_exp_mode,localization) 54 VALUES (%s,%s,%s,%s,%s,%s)', 55 array('integer', 'text', 'text', 'integer','integer','text'), 56 array($this->getId(),'API', $this->getSubType(),(int) $this->getEditable(), 57 (int) $this->getSequencingExpertMode(), $this->getLocalization() 58 ) 59 ); 60 } 61 62 /** 63 * read object 64 */ 65 public function read() 66 { 67 global $DIC; 68 $ilDB = $DIC['ilDB']; 69 70 parent::read(); 71 72 $lm_set = $ilDB->queryF( 73 'SELECT * FROM sahs_lm WHERE id = %s', 74 array('integer'), 75 array($this->getId()) 76 ); 77 78 while ($lm_rec = $ilDB->fetchAssoc($lm_set)) { 79 $this->setAutoReviewChar($lm_rec["auto_review"]); 80 $this->setAPIAdapterName($lm_rec["api_adapter"]); 81 $this->setDefaultLessonMode($lm_rec["default_lesson_mode"]); 82 $this->setAPIFunctionsPrefix($lm_rec["api_func_prefix"]); 83 $this->setCreditMode($lm_rec["credit"]); 84 $this->setSubType($lm_rec["c_type"]); 85 $this->setEditable($lm_rec["editable"]); 86 $this->setStyleSheetId($lm_rec["stylesheet"]); 87 $this->setMaxAttempt($lm_rec["max_attempt"]); 88 $this->setModuleVersion($lm_rec["module_version"]); 89 $this->setAssignedGlossary($lm_rec["glossary"]); 90 $this->setTries($lm_rec["question_tries"]); 91 $this->setLocalization($lm_rec["localization"]); 92 $this->setSession(ilUtil::yn2tf($lm_rec["unlimited_session"])); 93 $this->setNoMenu(ilUtil::yn2tf($lm_rec["no_menu"])); 94 $this->setHideNavig(ilUtil::yn2tf($lm_rec["hide_navig"])); 95 $this->setFourth_edition(ilUtil::yn2tf($lm_rec["fourth_edition"])); 96 $this->setSequencing(ilUtil::yn2tf($lm_rec["sequencing"])); 97 $this->setInteractions(ilUtil::yn2tf($lm_rec["interactions"])); 98 $this->setObjectives(ilUtil::yn2tf($lm_rec["objectives"])); 99 $this->setComments(ilUtil::yn2tf($lm_rec["comments"])); 100 $this->setTime_from_lms(ilUtil::yn2tf($lm_rec["time_from_lms"])); 101 $this->setDebug(ilUtil::yn2tf($lm_rec["debug"])); 102 $this->setDebugPw($lm_rec["debugpw"]); 103 $this->setSequencingExpertMode($lm_rec["seq_exp_mode"]); 104 $this->setOpenMode($lm_rec["open_mode"]); 105 $this->setWidth($lm_rec["width"]); 106 $this->setHeight($lm_rec["height"]); 107 $this->setAutoContinue(ilUtil::yn2tf($lm_rec["auto_continue"])); 108 $this->setAuto_last_visited(ilUtil::yn2tf($lm_rec["auto_last_visited"])); 109 $this->setCheck_values(ilUtil::yn2tf($lm_rec["check_values"])); 110 $this->setOfflineMode(ilUtil::yn2tf($lm_rec["offline_mode"])); 111 $this->setAutoSuspend(ilUtil::yn2tf($lm_rec["auto_suspend"])); 112 $this->setIe_force_render(ilUtil::yn2tf($lm_rec["ie_force_render"])); 113 $this->setMasteryScore($lm_rec["mastery_score"]); 114 $this->setIdSetting($lm_rec["id_setting"]); 115 $this->setNameSetting($lm_rec["name_setting"]); 116 117 include_once("./Services/Style/Content/classes/class.ilObjStyleSheet.php"); 118 if (ilObject::_lookupType($this->getStyleSheetId()) != "sty") { 119 $this->setStyleSheetId(0); 120 } 121 } 122 } 123 124 125 /** 126 * Get affective localization 127 * 128 * @param int $a_id scorm lm id 129 */ 130 public static function getAffectiveLocalization($a_id) 131 { 132 global $DIC; 133 $ilDB = $DIC['ilDB']; 134 $lng = $DIC['lng']; 135 136 $lm_set = $ilDB->queryF( 137 'SELECT localization FROM sahs_lm WHERE id = %s', 138 array('integer'), 139 array($a_id) 140 ); 141 $lm_rec = $ilDB->fetchAssoc($lm_set); 142 $inst_lang = $lng->getInstalledLanguages(); 143 if ($lm_rec["localization"] != "" && in_array($lm_rec["localization"], $inst_lang)) { 144 return $lm_rec["localization"]; 145 } 146 return $lng->getLangKey(); 147 } 148 149 /** 150 * lookup subtype id (scorm, ) 151 * 152 * @param int $a_id object id 153 */ 154 public static function _lookupSubType($a_obj_id) 155 { 156 global $DIC; 157 $ilDB = $DIC['ilDB']; 158 159 $obj_set = $ilDB->queryF( 160 'SELECT c_type FROM sahs_lm WHERE id = %s', 161 array('integer'), 162 array($a_obj_id) 163 ); 164 $obj_rec = $ilDB->fetchAssoc($obj_set); 165 166 return $obj_rec["c_type"]; 167 } 168 169 /** 170 * Set Editable. 171 * 172 * @param boolean $a_editable Editable 173 */ 174 public function setEditable($a_editable) 175 { 176 $this->editable = $a_editable; 177 } 178 179 /** 180 * Get Editable. 181 * 182 * @return boolean Editable 183 */ 184 public function getEditable() 185 { 186 return $this->editable; 187 } 188 189 190 /** 191 * Set default tries for questions 192 * 193 * @param boolean $a_tres tries 194 */ 195 public function setTries($a_tries) 196 { 197 $this->tries = $a_tries; 198 } 199 200 /** 201 * Get Tries. 202 * 203 * @return boolean tries 204 */ 205 public function getTries() 206 { 207 return $this->tries; 208 } 209 210 /** 211 * Set localization 212 * 213 * @param string $a_val localization 214 */ 215 public function setLocalization($a_val) 216 { 217 $this->localization = $a_val; 218 } 219 220 /** 221 * Get localization 222 * 223 * @return string localization 224 */ 225 public function getLocalization() 226 { 227 return $this->localization; 228 } 229 230 public static function _getTries($a_id) 231 { 232 global $DIC; 233 $ilDB = $DIC['ilDB']; 234 235 $lm_set = $ilDB->queryF( 236 'SELECT question_tries FROM sahs_lm WHERE id = %s', 237 array('integer'), 238 array($a_id) 239 ); 240 $lm_rec = $ilDB->fetchAssoc($lm_set); 241 242 return $lm_rec['question_tries']; 243 } 244 /** 245 * Gets the disk usage of the object in bytes. 246 * 247 * @access public 248 * @return integer the disk usage in bytes 249 */ 250 public function getDiskUsage() 251 { 252 require_once("./Modules/ScormAicc/classes/class.ilObjSAHSLearningModuleAccess.php"); 253 return ilObjSAHSLearningModuleAccess::_lookupDiskUsage($this->id); 254 } 255 256 257 /** 258 * creates data directory for package files 259 * ("./data/lm_data/lm_<id>") 260 */ 261 public function createDataDirectory() 262 { 263 $lm_data_dir = ilUtil::getWebspaceDir() . "/lm_data"; 264 ilUtil::makeDir($lm_data_dir); 265 ilUtil::makeDir($this->getDataDirectory()); 266 } 267 268 /** 269 * get data directory of lm 270 */ 271 public function getDataDirectory($mode = "filesystem") 272 { 273 $lm_data_dir = ilUtil::getWebspaceDir($mode) . "/lm_data"; 274 $lm_dir = $lm_data_dir . "/lm_" . $this->getId(); 275 276 return $lm_dir; 277 } 278 279 /** 280 * get api adapter name 281 */ 282 public function getAPIAdapterName() 283 { 284 return $this->api_adapter; 285 } 286 287 /** 288 * set api adapter name 289 */ 290 public function setAPIAdapterName($a_api) 291 { 292 $this->api_adapter = $a_api; 293 } 294 295 /** 296 * get api functions prefix 297 */ 298 public function getAPIFunctionsPrefix() 299 { 300 return $this->api_func_prefix; 301 } 302 303 /** 304 * set api functions prefix 305 */ 306 public function setAPIFunctionsPrefix($a_prefix) 307 { 308 $this->api_func_prefix = $a_prefix; 309 } 310 311 /** 312 * get credit mode 313 */ 314 public function getCreditMode() 315 { 316 return $this->credit_mode; 317 } 318 319 /** 320 * set credit mode 321 */ 322 public function setCreditMode($a_credit_mode) 323 { 324 $this->credit_mode = $a_credit_mode; 325 } 326 327 /** 328 * set default lesson mode 329 */ 330 public function setDefaultLessonMode($a_lesson_mode) 331 { 332 $this->lesson_mode = $a_lesson_mode; 333 } 334 335 /** 336 * get default lesson mode 337 */ 338 public function getDefaultLessonMode() 339 { 340 global $DIC; 341 if ($DIC['ilUser']->getId() == 13) { 342 return "browse"; 343 } 344 return $this->lesson_mode; 345 } 346 /** 347 * get ID of assigned style sheet object 348 */ 349 public function getStyleSheetId() 350 { 351 return $this->style_id; 352 } 353 354 /** 355 * set ID of assigned style sheet object 356 */ 357 public function setStyleSheetId($a_style_id) 358 { 359 $this->style_id = $a_style_id; 360 } 361 362 363 /** 364 * set auto review as true/false for SCORM 1.2 365 */ 366 public function setAutoReview($a_auto_review) 367 { 368 $this->auto_review = ilUtil::tf2yn($a_auto_review); 369 } 370 /** 371 * get auto review as true/false for SCORM 1.2 372 */ 373 public function getAutoReview() 374 { 375 return ilUtil::yn2tf($this->auto_review); 376 } 377 378 /** 379 * set auto review as Char for SCORM 2004 380 */ 381 public function setAutoReviewChar($a_auto_review) 382 { 383 $this->auto_review = $a_auto_review; 384 } 385 /** 386 * get auto review as Char for SCORM 2004 387 */ 388 public function getAutoReviewChar() 389 { 390 return $this->auto_review; 391 } 392 393 /** 394 * get max attempt 395 */ 396 public function getMaxAttempt() 397 { 398 return $this->max_attempt; 399 } 400 401 402 /** 403 * set max attempt 404 */ 405 public function setMaxAttempt($a_max_attempt) 406 { 407 $this->max_attempt = $a_max_attempt; 408 } 409 410 /** 411 * get module version 412 */ 413 public function getModuleVersion() 414 { 415 return $this->module_version; 416 } 417 418 /** 419 * get assigned glossary 420 */ 421 public function getAssignedGlossary() 422 { 423 return $this->assigned_glossary; 424 } 425 426 /** 427 * set assigned glossary 428 */ 429 public function setAssignedGlossary($a_assigned_glossary) 430 { 431 $this->assigned_glossary = $a_assigned_glossary; 432 } 433 /** 434 * set max attempt 435 */ 436 public function setModuleVersion($a_module_version) 437 { 438 $this->module_version = $a_module_version; 439 } 440 441 /** 442 * get session setting 443 */ 444 public function getSession() 445 { 446 return $this->session; 447 } 448 449 /** 450 * set session setting 451 */ 452 public function setSession($a_session) 453 { 454 $this->session = $a_session; 455 } 456 457 /** 458 * disable menu 459 */ 460 public function getNoMenu() 461 { 462 return $this->no_menu; 463 } 464 465 /** 466 * disable menu 467 */ 468 public function setNoMenu($a_no_menu) 469 { 470 $this->no_menu = $a_no_menu; 471 } 472 473 /** 474 * hide navigation tree 475 */ 476 public function getHideNavig() 477 { 478 return $this->hide_navig; 479 } 480 481 /** 482 * disable menu 483 */ 484 public function setHideNavig($a_hide_navig) 485 { 486 $this->hide_navig = $a_hide_navig; 487 } 488 489 /** 490 * BrowserCacheDisabled for SCORM 2004 / ENABLE_JS_DEBUG 491 */ 492 public function getCacheDeactivated() 493 { 494 global $DIC; 495 $ilSetting = $DIC['ilSetting']; 496 $lm_set = new ilSetting("lm"); 497 if ($lm_set->get("scormdebug_disable_cache") == "1") { 498 return true; 499 } 500 return false; 501 } 502 503 /** 504 * sessionDisabled for SCORM 2004 505 */ 506 public function getSessionDeactivated() 507 { 508 global $DIC; 509 $ilSetting = $DIC['ilSetting']; 510 $lm_set = new ilSetting("lm"); 511 if ($lm_set->get("scorm_without_session") == "1") { 512 return true; 513 } 514 return false; 515 } 516 517 /** 518 * debugActivated 519 */ 520 public function getDebugActivated() 521 { 522 global $DIC; 523 $ilSetting = $DIC['ilSetting']; 524 $lm_set = new ilSetting("lm"); 525 if ($lm_set->get("scormdebug_global_activate") == "1") { 526 return true; 527 } 528 return false; 529 } 530 531 /** 532 * force Internet Explorer to render again after some Milliseconds - useful for learning Modules with a lot of iframesor frames and IE >=10 533 */ 534 public function getIe_force_render() 535 { 536 return $this->ie_force_render; 537 } 538 539 public function setIe_force_render($a_ie_force_render) 540 { 541 $this->ie_force_render = $a_ie_force_render; 542 } 543 544 /** 545 * SCORM 2004 4th edition features 546 */ 547 public function getFourth_Edition() 548 { 549 return $this->fourth_edition; 550 } 551 552 public function setFourth_edition($a_fourth_edition) 553 { 554 $this->fourth_edition = $a_fourth_edition; 555 } 556 557 /** 558 * sequencing 559 */ 560 public function getSequencing() 561 { 562 return $this->sequencing; 563 } 564 565 public function setSequencing($a_sequencing) 566 { 567 $this->sequencing = $a_sequencing; 568 } 569 570 /** 571 * interactions 572 */ 573 public function getInteractions() 574 { 575 return $this->interactions; 576 } 577 578 public function setInteractions($a_interactions) 579 { 580 $this->interactions = $a_interactions; 581 } 582 583 /** 584 * objectives 585 */ 586 public function getObjectives() 587 { 588 return $this->objectives; 589 } 590 591 public function setObjectives($a_objectives) 592 { 593 $this->objectives = $a_objectives; 594 } 595 596 /** 597 * comments 598 */ 599 public function getComments() 600 { 601 return $this->comments; 602 } 603 604 public function setComments($a_comments) 605 { 606 $this->comments = $a_comments; 607 } 608 609 /** 610 * time_from_lms 611 */ 612 public function getTime_from_lms() 613 { 614 return $this->time_from_lms; 615 } 616 617 public function setTime_from_lms($a_time_from_lms) 618 { 619 $this->time_from_lms = $a_time_from_lms; 620 } 621 622 /** 623 * check_values 624 */ 625 public function getCheck_values() 626 { 627 return $this->check_values; 628 } 629 630 public function setCheck_values($a_check_values) 631 { 632 $this->check_values = $a_check_values; 633 } 634 635 /** 636 * offlineMode 637 */ 638 public function getOfflineMode() 639 { 640 return $this->offline_mode; 641 } 642 643 public function setOfflineMode($a_offline_mode) 644 { 645 $this->offline_mode = $a_offline_mode; 646 } 647 648 649 /** 650 * debug 651 */ 652 public function getDebug() 653 { 654 return $this->debug; 655 } 656 657 /** 658 * debug 659 */ 660 public function setDebug($a_debug) 661 { 662 $this->debug = $a_debug; 663 } 664 665 /** 666 * debug pw 667 */ 668 public function getDebugPw() 669 { 670 return $this->debug_pw; 671 } 672 673 /** 674 * debug pw 675 */ 676 public function setDebugPw($a_debug_pw) 677 { 678 $this->debug_pw = $a_debug_pw; 679 } 680 681 /** 682 * get auto continue 683 */ 684 public function setAutoContinue($a_auto_continue) 685 { 686 $this->auto_continue = $a_auto_continue; 687 } 688 /** 689 * set auto continue 690 */ 691 public function getAutoContinue() 692 { 693 return $this->auto_continue; 694 } 695 696 /** 697 * auto_last_visited 698 */ 699 public function getAuto_last_visited() 700 { 701 return $this->auto_last_visited; 702 } 703 704 public function setAuto_last_visited($a_auto_last_visited) 705 { 706 $this->auto_last_visited = $a_auto_last_visited; 707 } 708 709 710 /** 711 * Set sequencing expert mode 712 * 713 * @param boolean $a_val sequencing expert mode 714 */ 715 public function setSequencingExpertMode($a_val) 716 { 717 $this->seq_exp_mode = $a_val; 718 } 719 720 /** 721 * Get sequencing expert mode 722 * 723 * @return boolean sequencing expert mode 724 */ 725 public function getSequencingExpertMode() 726 { 727 return $this->seq_exp_mode; 728 } 729 730 /** 731 * get auto continue 732 */ 733 public function setAutoSuspend($a_auto_suspend) 734 { 735 $this->auto_suspend = $a_auto_suspend; 736 } 737 /** 738 * set auto continue 739 */ 740 public function getAutoSuspend() 741 { 742 return $this->auto_suspend; 743 } 744 745 746 /** 747 * open_mode 748 * 0: in Tab/new Window like in previous versions 749 * 1: in iFrame with width=100% and heigth=100% 750 * 2: in iFrame with specified width and height 751 * 3: 752 * 4: 753 * 5: in new Window without specified width and height 754 * 6: in new Window with specified width and height 755 */ 756 public function getOpenMode() 757 { 758 return $this->open_mode; 759 } 760 public function setOpenMode($a_open_mode) 761 { 762 $this->open_mode = $a_open_mode; 763 } 764 765 /** 766 * width 767 */ 768 public function getWidth() 769 { 770 return $this->width; 771 } 772 public function setWidth($a_width) 773 { 774 $this->width = $a_width; 775 } 776 777 /** 778 * height 779 */ 780 public function getHeight() 781 { 782 return $this->height; 783 } 784 public function setHeight($a_height) 785 { 786 $this->height = $a_height; 787 } 788 789 790 /** 791 * get mastery_score 792 */ 793 public function getMasteryScore() 794 { 795 return $this->mastery_score; 796 } 797 798 /** 799 * set mastery_score 800 */ 801 public function setMasteryScore($a_mastery_score) 802 { 803 $this->mastery_score = $a_mastery_score; 804 } 805 806 /** 807 * check mastery_score / min_normalized_measure of SCOs (SCORM 1.2) / objectives (SCORM 2004) 808 */ 809 public function checkMasteryScoreValues() 810 { 811 global $DIC; 812 $ilDB = $DIC['ilDB']; 813 $s_result = ""; 814 $a_result = array(); 815 $type = $this->_lookupSubType($this->getID()); 816 817 if ($type == "scorm2004") { 818 $set = $ilDB->query("SELECT minnormalmeasure FROM cp_objective, cp_node" . 819 " WHERE satisfiedbymeasure=1 AND minnormalmeasure is not null AND cp_objective.cp_node_id=cp_node.cp_node_id AND" . 820 " slm_id = " . $ilDB->quote($this->getID(), "integer")); 821 while ($rec = $ilDB->fetchAssoc($set)) { 822 $tmpval = $rec["minnormalmeasure"] * 100; 823 if (!in_array($tmpval, $a_result)) { 824 $a_result[] = $tmpval; 825 } 826 } 827 } else { 828 $set = $ilDB->query("SELECT masteryscore FROM sc_item,scorm_object" . 829 " WHERE sc_item.masteryscore is not null AND sc_item.obj_id=scorm_object.obj_id AND" . 830 " slm_id = " . $ilDB->quote($this->getID(), "integer")); 831 while ($rec = $ilDB->fetchAssoc($set)) { 832 if (!in_array($rec["masteryscore"], $a_result)) { 833 $a_result[] = $rec["masteryscore"]; 834 } 835 } 836 } 837 $s_result = implode(", ", $a_result); 838 $this->mastery_score_values = $s_result; 839 } 840 841 /** 842 * get mastery_score_values 843 */ 844 public function getMasteryScoreValues() 845 { 846 return $this->mastery_score_values; 847 } 848 849 /** 850 * update values for mastery_score / min_normalized_measure in database - not requested 851 */ 852 /* 853 function updateMasteryScoreValues() 854 { 855 global $DIC; 856 $ilDB = $DIC['ilDB']; 857 $s_mastery_score = $this->getMasteryScore(); 858 if ($s_mastery_score != "" && is_numeric($s_mastery_score)) { 859 $i_mastery_score = round(intval($s_mastery_score,10)); 860 $type = $this->_lookupSubType( $this->getID() ); 861 862 if ($type == "scorm2004") { 863 if ($i_mastery_score > 100) $i_mastery_score = 100; 864 $i_mastery_score = $i_mastery_score/100; 865 $statement = $ilDB->manipulateF( 866 'UPDATE cp_objective,cp_node SET minnormalmeasure = %s 867 WHERE satisfiedbymeasure=1 AND minnormalmeasure is not null AND cp_objective.cp_node_id=cp_node.cp_node_id AND slm_id = %s', 868 array('text','integer'), 869 array($i_mastery_score,$this->getID()) 870 ); 871 } else { 872 if ($i_mastery_score > 127) $i_mastery_score = 127; 873 $statement = $ilDB->manipulateF( 874 'UPDATE sc_item,scorm_object SET sc_item.masteryscore = %s 875 WHERE sc_item.masteryscore is not null AND sc_item.obj_id=scorm_object.obj_id AND slm_id = %s', 876 array('integer','integer'), 877 array($i_mastery_score,$this->getID()) 878 ); 879 } 880 } 881 } 882 */ 883 884 /** 885 * update meta data only 886 */ 887 /* 888 function updateMetaData() 889 { 890 $this->meta_data->update(); 891 if ($this->meta_data->section != "General") 892 { 893 $meta = $this->meta_data->getElement("Title", "General"); 894 $this->meta_data->setTitle($meta[0]["value"]); 895 $meta = $this->meta_data->getElement("Description", "General"); 896 $this->meta_data->setDescription($meta[0]["value"]); 897 } 898 else 899 { 900 $this->setTitle($this->meta_data->getTitle()); 901 $this->setDescription($this->meta_data->getDescription()); 902 } 903 parent::update(); 904 905 } 906 */ 907 908 /** 909 * get id_setting 910 */ 911 public function getIdSetting() 912 { 913 return $this->id_setting; 914 } 915 916 /** 917 * set id_setting 918 */ 919 public function setIdSetting($a_id_setting) 920 { 921 $this->id_setting = $a_id_setting; 922 } 923 924 /** 925 * get name_setting 926 */ 927 public function getNameSetting() 928 { 929 return $this->name_setting; 930 } 931 932 /** 933 * set name_setting 934 */ 935 public function setNameSetting($a_name_setting) 936 { 937 $this->name_setting = $a_name_setting; 938 } 939 940 941 942 943 /** 944 * update object data 945 * 946 * @access public 947 * @return boolean 948 */ 949 public function update() 950 { 951 global $DIC; 952 $ilDB = $DIC['ilDB']; 953 954 $this->updateMetaData(); 955 parent::update(); 956 957 $s_mastery_score = $this->getMasteryScore(); 958 if ($s_mastery_score == "") { 959 $s_mastery_score = null; 960 } 961 962 $statement = $ilDB->manipulateF( 963 ' 964 UPDATE sahs_lm 965 SET api_adapter = %s, 966 api_func_prefix = %s, 967 auto_review = %s, 968 default_lesson_mode = %s, 969 c_type = %s, 970 stylesheet = %s, 971 editable = %s, 972 max_attempt = %s, 973 module_version = %s, 974 credit = %s, 975 glossary = %s, 976 question_tries = %s, 977 unlimited_session = %s, 978 no_menu = %s, 979 hide_navig = %s, 980 fourth_edition =%s, 981 sequencing = %s, 982 interactions = %s, 983 objectives = %s, 984 comments = %s, 985 time_from_lms = %s, 986 debug = %s, 987 localization = %s, 988 seq_exp_mode = %s, 989 debugpw = %s, 990 open_mode = %s, 991 width = %s, 992 height = %s, 993 auto_continue = %s, 994 auto_last_visited = %s, 995 check_values = %s, 996 offline_mode = %s, 997 auto_suspend = %s, 998 ie_force_render = %s, 999 mastery_score = %s, 1000 id_setting = %s, 1001 name_setting = %s 1002 WHERE id = %s', 1003 array( 'text', 1004 'text', 1005 'text', 1006 'text', 1007 'text', 1008 'integer', 1009 'integer', 1010 'integer', 1011 'integer', 1012 'text', 1013 'integer', 1014 'integer', 1015 'text', 1016 'text', 1017 'text', 1018 'text', 1019 'text', 1020 'text', 1021 'text', 1022 'text', 1023 'text', 1024 'text', 1025 'text', 1026 'integer', 1027 'text', 1028 'integer', 1029 'integer', 1030 'integer', 1031 'text', 1032 'text', 1033 'text', 1034 'text', 1035 'text', 1036 'text', 1037 'integer', 1038 'integer', 1039 'integer', 1040 'integer' 1041 ), 1042 array( $this->getAPIAdapterName(), 1043 $this->getAPIFunctionsPrefix(), 1044 $this->getAutoReviewChar(), 1045 $this->getDefaultLessonMode(), 1046 $this->getSubType(), 1047 $this->getStyleSheetId(), 1048 $this->getEditable(), 1049 $this->getMaxAttempt(), 1050 $this->getModuleVersion(), 1051 $this->getCreditMode(), 1052 $this->getAssignedGlossary(), 1053 $this->getTries(), 1054 ilUtil::tf2yn($this->getSession()), 1055 ilUtil::tf2yn($this->getNoMenu()), 1056 ilUtil::tf2yn($this->getHideNavig()), 1057 ilUtil::tf2yn($this->getFourth_edition()), 1058 ilUtil::tf2yn($this->getSequencing()), 1059 ilUtil::tf2yn($this->getInteractions()), 1060 ilUtil::tf2yn($this->getObjectives()), 1061 ilUtil::tf2yn($this->getComments()), 1062 ilUtil::tf2yn($this->getTime_from_lms()), 1063 ilUtil::tf2yn($this->getDebug()), 1064 $this->getLocalization(), 1065 $this->getSequencingExpertMode(), 1066 $this->getDebugPw(), 1067 $this->getOpenMode(), 1068 $this->getWidth(), 1069 $this->getHeight(), 1070 ilUtil::tf2yn($this->getAutoContinue()), 1071 ilUtil::tf2yn($this->getAuto_last_visited()), 1072 ilUtil::tf2yn($this->getCheck_values()), 1073 ilUtil::tf2yn($this->getOfflineMode()), 1074 ilUtil::tf2yn($this->getAutoSuspend()), 1075 ilUtil::tf2yn($this->getIe_force_render()), 1076 $s_mastery_score, 1077 $this->getIdSetting(), 1078 $this->getNameSetting(), 1079 $this->getId()) 1080 ); 1081 1082 return true; 1083 } 1084 1085 /** 1086 * Get SCORM modules that assign a certain glossary 1087 * 1088 * @param 1089 * @return 1090 */ 1091 public static function getScormModulesForGlossary($a_glo_id) 1092 { 1093 global $DIC; 1094 $ilDB = $DIC['ilDB']; 1095 1096 $set = $ilDB->query("SELECT DISTINCT id FROM sahs_lm WHERE " . 1097 " glossary = " . $ilDB->quote($a_glo_id, "integer")); 1098 $sms = array(); 1099 while ($rec = $ilDB->fetchAssoc($set)) { 1100 if (ilObject::_hasUntrashedReference($rec["id"])) { 1101 $sms[] = $rec["id"]; 1102 } 1103 } 1104 return $sms; 1105 } 1106 1107 /** 1108 * Get SCORM modules that assign a certain glossary 1109 * 1110 * @param 1111 * @return 1112 */ 1113 public static function lookupAssignedGlossary($a_slm_id) 1114 { 1115 global $DIC; 1116 $ilDB = $DIC['ilDB']; 1117 1118 $set = $ilDB->query("SELECT DISTINCT glossary FROM sahs_lm WHERE " . 1119 " id = " . $ilDB->quote($a_slm_id, "integer")); 1120 $rec = $ilDB->fetchAssoc($set); 1121 $glo_id = $rec["glossary"]; 1122 if (ilObject::_lookupType($glo_id) == "glo") { 1123 return $glo_id; 1124 } 1125 return 0; 1126 } 1127 1128 1129 /** 1130 * get sub type 1131 */ 1132 public function setSubType($a_sub_type) 1133 { 1134 $this->sub_type = $a_sub_type; 1135 } 1136 1137 /** 1138 * set sub type 1139 */ 1140 public function getSubType() 1141 { 1142 return $this->sub_type; 1143 } 1144 1145 /** 1146 * delete SCORM learning module and all related data 1147 * 1148 * this method has been tested on may 9th 2004 1149 * meta data, scorm lm data, scorm tree, scorm objects (organization(s), 1150 * manifest, resources and items), tracking data and data directory 1151 * have been deleted correctly as desired 1152 * 1153 * @access public 1154 * @return boolean true if all object data were removed; false if only a references were removed 1155 */ 1156 public function delete() 1157 { 1158 global $DIC; 1159 $ilDB = $DIC['ilDB']; 1160 $ilLog = $DIC['ilLog']; 1161 1162 // always call parent delete function first!! 1163 if (!parent::delete()) { 1164 return false; 1165 } 1166 1167 // delete meta data of scorm content object 1168 $this->deleteMetaData(); 1169 1170 // delete data directory 1171 ilUtil::delDir($this->getDataDirectory()); 1172 1173 // delete scorm learning module record 1174 $ilDB->manipulateF( 1175 'DELETE FROM sahs_lm WHERE id = %s', 1176 array('integer'), 1177 array($this->getId()) 1178 ); 1179 1180 $ilLog->write("SAHS Delete(SAHSLM), Subtype: " . $this->getSubType()); 1181 1182 if ($this->getSubType() == "scorm") { 1183 // remove all scorm objects and scorm tree 1184 include_once("./Modules/ScormAicc/classes/SCORM/class.ilSCORMTree.php"); 1185 include_once("./Modules/ScormAicc/classes/SCORM/class.ilSCORMObject.php"); 1186 $sc_tree = new ilSCORMTree($this->getId()); 1187 $r_id = $sc_tree->readRootId(); 1188 if ($r_id > 0) { 1189 $items = $sc_tree->getSubTree($sc_tree->getNodeData($r_id)); 1190 foreach ($items as $item) { 1191 $sc_object = ilSCORMObject::_getInstance($item["obj_id"], $this->getId()); 1192 if (is_object($sc_object)) { 1193 $sc_object->delete(); 1194 } 1195 } 1196 $sc_tree->removeTree($sc_tree->getTreeId()); 1197 } 1198 } 1199 1200 if ($this->getSubType() != "scorm") { 1201 // delete aicc data 1202 $res = $ilDB->queryF( 1203 ' 1204 SELECT aicc_object.obj_id FROM aicc_object, aicc_units 1205 WHERE aicc_object.obj_id = aicc_units.obj_id 1206 AND aicc_object.slm_id = %s', 1207 array('integer'), 1208 array($this->getId()) 1209 ); 1210 1211 while ($row = $ilDB->fetchAssoc($res)) { 1212 $obj_id = $row['obj_id']; 1213 $ilDB->manipulateF( 1214 ' 1215 DELETE FROM aicc_units WHERE obj_id = %s', 1216 array('integer'), 1217 array($obj_id) 1218 ); 1219 } 1220 1221 $res = $ilDB->queryF( 1222 ' 1223 SELECT aicc_object.obj_id FROM aicc_object, aicc_course 1224 WHERE aicc_object.obj_id = aicc_course.obj_id 1225 AND aicc_object.slm_id = %s', 1226 array('integer'), 1227 array($this->getId()) 1228 ); 1229 1230 while ($row = $ilDB->fetchAssoc($res)) { 1231 $obj_id = $row['obj_id']; 1232 $ilDB->manipulateF( 1233 ' 1234 DELETE FROM aicc_course WHERE obj_id = %s', 1235 array('integer'), 1236 array($obj_id) 1237 ); 1238 } 1239 1240 $ilDB->manipulateF( 1241 ' 1242 DELETE FROM aicc_object WHERE slm_id = %s', 1243 array('integer'), 1244 array($this->getId()) 1245 ); 1246 } 1247 1248 $q_log = "DELETE FROM scorm_tracking WHERE obj_id = " . $ilDB->quote($this->getId()); 1249 $ilLog->write("SAHS Delete(SAHSLM): " . $q_log); 1250 1251 $ilDB->manipulateF( 1252 'DELETE FROM scorm_tracking WHERE obj_id = %s', 1253 array('integer'), 1254 array($this->getId()) 1255 ); 1256 1257 $q_log = "DELETE FROM sahs_user WHERE obj_id = " . $ilDB->quote($this->getId()); 1258 $ilLog->write("SAHS Delete(SAHSLM): " . $q_log); 1259 1260 $ilDB->manipulateF( 1261 'DELETE FROM sahs_user WHERE obj_id = %s', 1262 array('integer'), 1263 array($this->getId()) 1264 ); 1265 1266 // always call parent delete function at the end!! 1267 return true; 1268 } 1269 1270 /** 1271 * Returns the points in percent for the learning module 1272 * This is called by the certificate generator if [SCORM_POINTS] is 1273 * inserted. 1274 */ 1275 public function getPointsInPercent() 1276 { 1277 global $DIC; 1278 $ilUser = $DIC['ilUser']; 1279 if (strcmp($this->getSubType(), "scorm2004") == 0) { 1280 $res = ilObjSCORM2004LearningModule::_getUniqueScaledScoreForUser($this->getId(), $ilUser->getId()); 1281 if (!is_null($res)) { 1282 return $res * 100.0; 1283 } else { 1284 return $res; 1285 } 1286 } else { 1287 return null; 1288 } 1289 } 1290 1291 /** 1292 * 1293 * Returns score.max for the learning module, refered to the last sco where score.max is set. 1294 * This is called by the certificate generator if [SCORM_POINTS_MAX] is 1295 * inserted. 1296 * 1297 * @access public 1298 * @return float 1299 * 1300 */ 1301 public function getMaxPoints() 1302 { 1303 global $DIC; 1304 $ilUser = $DIC['ilUser']; 1305 1306 if (strcmp($this->getSubType(), 'scorm2004') == 0) { 1307 $res = ilObjSCORM2004LearningModule::_getMaxScoreForUser($this->getId(), $ilUser->getId()); 1308 return $res; 1309 } else { 1310 return null; 1311 } 1312 } 1313 1314 /** 1315 * Populate by directory. Add a filename to do a special check for 1316 * ILIAS SCORM export files. If the corresponding directory is found 1317 * within the passed directory path (i.e. "htlm_<id>") this 1318 * subdirectory is used instead. 1319 * 1320 * @param 1321 * @return 1322 */ 1323 public function populateByDirectoy($a_dir, $a_filename = "") 1324 { 1325 /*preg_match("/.*sahs_([0-9]*)\.zip/", $a_filename, $match); 1326 if (is_dir($a_dir."/sahs_".$match[1])) 1327 { 1328 $a_dir = $a_dir."/sahs_".$match[1]; 1329 }*/ 1330 ilUtil::rCopy($a_dir, $this->getDataDirectory()); 1331 ilUtil::renameExecutables($this->getDataDirectory()); 1332 } 1333 1334 1335 /** 1336 * Clone scorm object 1337 * 1338 * @param int target ref_id 1339 * @param int copy id 1340 */ 1341 public function cloneObject($a_target_id, $a_copy_id = 0, $a_omit_tree = false) 1342 { 1343 global $DIC; 1344 $ilDB = $DIC['ilDB']; 1345 $ilUser = $DIC['ilUser']; 1346 $ilias = $DIC['ilias']; 1347 $lng = $DIC['lng']; 1348 1349 $new_obj = parent::cloneObject($a_target_id, $a_copy_id, $a_omit_tree); 1350 $this->cloneMetaData($new_obj); 1351 1352 $new_obj->setOfflineStatus($this->getOfflineStatus()); 1353 //copy online status if object is not the root copy object 1354 $cp_options = ilCopyWizardOptions::_getInstance($a_copy_id); 1355 if ($cp_options->isRootNode($this->getRefId())) { 1356 $new_obj->setOfflineStatus(true); 1357 } 1358 1359 // copy properties 1360 // $new_obj->setTitle($this->getTitle() . ' ' . $lng->txt('copy_of_suffix')); 1361 $new_obj->setDescription($this->getDescription()); 1362 $new_obj->setSubType($this->getSubType()); 1363 $new_obj->setAPIAdapterName($this->getAPIAdapterName()); 1364 $new_obj->setAPIFunctionsPrefix($this->getAPIFunctionsPrefix()); 1365 $new_obj->setAutoReviewChar($this->getAutoReviewChar()); 1366 $new_obj->setDefaultLessonMode($this->getDefaultLessonMode()); 1367 $new_obj->setEditable($this->getEditable()); 1368 $new_obj->setMaxAttempt($this->getMaxAttempt()); 1369 $new_obj->setModuleVersion($this->getModuleVersion()); 1370 $new_obj->setModuleVersion(1); 1371 $new_obj->setCreditMode($this->getCreditMode()); 1372 $new_obj->setAssignedGlossary($this->getAssignedGlossary()); 1373 $new_obj->setTries($this->getTries()); 1374 $new_obj->setSession($this->getSession()); 1375 $new_obj->setNoMenu($this->getNoMenu()); 1376 $new_obj->setHideNavig($this->getHideNavig()); 1377 $new_obj->setFourth_edition($this->getFourth_edition()); 1378 $new_obj->setSequencing($this->getSequencing()); 1379 $new_obj->setInteractions($this->getInteractions()); 1380 $new_obj->setObjectives($this->getObjectives()); 1381 $new_obj->setComments($this->getComments()); 1382 $new_obj->setTime_from_lms($this->getTime_from_lms()); 1383 $new_obj->setDebug($this->getDebug()); 1384 $new_obj->setLocalization($this->getLocalization()); 1385 $new_obj->setSequencingExpertMode($this->getSequencingExpertMode()); 1386 $new_obj->setDebugPw($this->getDebugPw()); 1387 $new_obj->setOpenMode($this->getOpenMode()); 1388 $new_obj->setWidth($this->getWidth()); 1389 $new_obj->setHeight($this->getHeight()); 1390 $new_obj->setAutoContinue($this->getAutoContinue()); 1391 $new_obj->setAuto_last_visited($this->getAuto_last_visited()); 1392 $new_obj->setCheck_values($this->getCheck_values()); 1393 $new_obj->setOfflineMode($this->getOfflineMode()); 1394 $new_obj->setAutoSuspend($this->getAutoSuspend()); 1395 $new_obj->setIe_force_render($this->getIe_force_render()); 1396 $new_obj->setStyleSheetId($this->getStyleSheetId()); 1397 $new_obj->update(); 1398 1399 1400 // set/copy stylesheet 1401 /* include_once("./Services/Style/Content/classes/class.ilObjStyleSheet.php"); 1402 $style_id = $this->getStyleSheetId(); 1403 if ($style_id > 0 && !ilObjStyleSheet::_lookupStandard($style_id)) 1404 { 1405 $style_obj = $ilias->obj_factory->getInstanceByObjId($style_id); 1406 $new_id = $style_obj->ilClone(); 1407 $new_obj->setStyleSheetId($new_id); 1408 $new_obj->update(); 1409 }*/ 1410 1411 // up to this point $new_obj is of type ilobjsahslearning module 1412 1413 // create instance of correct subtype and call forward it to 1414 // cloneIntoNewObject method 1415 switch ($this->getSubType()) { 1416 case "scorm": 1417 include_once("./Modules/ScormAicc/classes/class.ilObjSCORMLearningModule.php"); 1418 $source_obj = new ilObjSCORMLearningModule($this->getRefId()); 1419 $new_obj = new ilObjSCORMLearningModule($new_obj->getRefId()); 1420 break; 1421 1422 case "scorm2004": 1423 include_once("./Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModule.php"); 1424 $source_obj = new ilObjSCORM2004LearningModule($this->getRefId()); 1425 $new_obj = new ilObjSCORM2004LearningModule($new_obj->getRefId()); 1426 break; 1427 } 1428 1429 // copy data directory 1430 $new_obj->populateByDirectoy($source_obj->getDataDirectory()); 1431 1432 // copy authored content ... 1433 if ($new_obj->getEditable()) { 1434 $source_obj->copyAuthoredContent($new_obj); 1435 } else { 1436 // ... or read manifest file 1437 $new_obj->readObject(); 1438 } 1439 1440 // Copy learning progress settings (Mantis #0022964) 1441 include_once('Services/Tracking/classes/class.ilLPObjSettings.php'); 1442 $obj_settings = new ilLPObjSettings($this->getId()); 1443 $obj_settings->cloneSettings($new_obj->getId()); 1444 1445 include_once('Services/Object/classes/class.ilObjectLP.php'); 1446 /** @var ilScormLP $olp */ 1447 $olp = ilObjectLP::getInstance($this->getId()); 1448 $collection = $olp->getCollectionInstance(); 1449 if ($collection) { 1450 $collection->cloneCollection($new_obj->getRefId(), $cp_options->getCopyId()); 1451 } 1452 return $new_obj; 1453 } 1454 1455 public function zipLmForOfflineMode() 1456 { 1457 $lmDir = ilUtil::getWebspaceDir("filesystem") . "/lm_data/lm_" . $this->getId(); 1458 $zipFile = ilUtil::getDataDir() . "/lm_data/lm_" . $this->getId(); 1459 return ilUtil::zip($lmDir, $zipFile, true); 1460 } 1461 1462 /** 1463 * Get cmi.core.student_id / cmi.learner_id for API 1464 */ 1465 public function getApiStudentId() 1466 { 1467 global $DIC; 1468 $ilias = $DIC['ilias']; 1469 $idSetting = $this->getIdSetting(); 1470 $studentId = $ilias->account->getId(); 1471 if ($idSetting % 2 == 1) { 1472 $studentId = $ilias->account->getLogin(); 1473 } 1474 if ($idSetting > 3) { 1475 $studentId .= '_o_' . $this->getId(); 1476 } elseif ($idSetting > 1) { 1477 $studentId .= '_r_' . $_GET["ref_id"]; 1478 } 1479 return $studentId; 1480 } 1481 1482 /** 1483 * Get cmi.core.student_name / cmi.learner_name for API 1484 * note: 'lastname, firstname' is required for SCORM 1.2; 9 = no name to hide student_name for external content 1485 */ 1486 public function getApiStudentName() 1487 { 1488 global $DIC; 1489 $ilias = $DIC['ilias']; 1490 $lng = $DIC['lng']; 1491 $studentName = " "; 1492 switch ($this->getNameSetting()) { 1493 case 0: 1494 $studentName = $ilias->account->getLastname() . ', ' . $ilias->account->getFirstname(); 1495 break; 1496 case 1: 1497 $studentName = $ilias->account->getFirstname() . ' ' . $ilias->account->getLastname(); 1498 break; 1499 case 2: 1500 $studentName = $ilias->account->getFullname(); 1501 break; 1502 case 3: 1503 switch ($ilias->account->getGender()) { 1504 case 'f': 1505 $studentName = $lng->txt('salutation_f') . ' '; 1506 break; 1507 1508 case 'm': 1509 $studentName = $lng->txt('salutation_m') . ' '; 1510 break; 1511 1512 case 'n': 1513 $studentName = '';//$lng->txt('salutation_n'); 1514 break; 1515 1516 default: 1517 $studentName = $lng->txt('salutation') . ' '; 1518 } 1519 $studentName .= $ilias->account->getLastname(); 1520 break; 1521 case 4: 1522 $studentName = $ilias->account->getFirstname(); 1523 break; 1524 } 1525 return $studentName; 1526 } 1527 1528 /** 1529 * get button for view 1530 */ 1531 public function getViewButton() 1532 { 1533 $setUrl = "ilias.php?baseClass=ilSAHSPresentationGUI&ref_id=" . $this->getRefID(); 1534 // $setUrl = $this->getLinkTargetByClass("ilsahspresentationgui", "")."&ref_id=".$this->getRefID(); 1535 $setTarget = "ilContObj" . $this->getId(); 1536 $om = $this->getOpenMode(); 1537 $width = $this->getWidth(); 1538 $height = $this->getHeight(); 1539 if (($om == 5 || $om == 1) && $width > 0 && $height > 0) { 1540 $om++; 1541 } 1542 if ($om != 0) { 1543 $setUrl = "javascript:void(0); onclick=startSAHS('" . $setUrl . "','ilContObj" . $this->getId() . "'," . $om . "," . $width . "," . $height . ");"; 1544 $setTarget = ""; 1545 } 1546 include_once "Services/UIComponent/Button/classes/class.ilLinkButton.php"; 1547 $button = ilLinkButton::getInstance(); 1548 $button->setCaption("view"); 1549 $button->setPrimary(true); 1550 $button->setUrl($setUrl); 1551 $button->setTarget($setTarget); 1552 return $button; 1553 } 1554} 1555