ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilObjSCORM2004LearningModule.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
5 require_once "./Modules/ScormAicc/classes/class.ilObjSCORMLearningModule.php";
6 
16 {
20  protected $user;
21 
25  protected $tabs;
26 
27  public $validator;
28  // var $meta_data;
29 
30  const CONVERT_XSL = './Modules/Scorm2004/templates/xsl/op/scorm12To2004.xsl';
31  const WRAPPER_HTML = './Modules/Scorm2004/scripts/converter/GenericRunTimeWrapper1.0_aadlc/GenericRunTimeWrapper.htm';
32  const WRAPPER_JS = './Modules/Scorm2004/scripts/converter/GenericRunTimeWrapper1.0_aadlc/SCOPlayerWrapper.js';
33 
40  public function __construct($a_id = 0, $a_call_by_reference = true)
41  {
42  global $DIC;
43 
44  $this->lng = $DIC->language();
45  $this->error = $DIC["ilErr"];
46  $this->db = $DIC->database();
47  $this->log = $DIC["ilLog"];
48  $this->user = $DIC->user();
49  $this->tabs = $DIC->tabs();
50  $this->type = "sahs";
51  parent::__construct($a_id, $a_call_by_reference);
52  }
53 
59  public function setImportSequencing($a_val)
60  {
61  $this->import_sequencing = $a_val;
62  }
63 
69  public function getImportSequencing()
70  {
71  return $this->import_sequencing;
72  }
73 
80  public function validate($directory)
81  {
82  //$this->validator = new ilObjSCORMValidator($directory);
83  //$returnValue = $this->validator->validate();
84  return true;
85  }
86 
91  public function readObject()
92  {
93  global $DIC;
94  $lng = $this->lng;
96 
97  //check for json_encode,json_decode
98  if (!function_exists('json_encode') || !function_exists('json_decode')) {
99  $ilErr->raiseError($lng->txt('scplayer_phpmysqlcheck'), $ilErr->WARNING);
100  }
101 
102  $needs_convert = false;
103 
104  // convert imsmanifest.xml file in iso to utf8 if needed
105 
106  $manifest_file = $this->getDataDirectory() . "/imsmanifest.xml";
107 
108  // check if manifestfile exists and space left on device...
109  $check_for_manifest_file = is_file($manifest_file);
110 
111 
112 
113  // if no manifestfile
114  if (!$check_for_manifest_file) {
115  $ilErr->raiseError($this->lng->txt("Manifestfile $manifest_file not found!"), $ilErr->MESSAGE);
116  return;
117  }
118 
119 
120  if ($check_for_manifest_file) {
121  $manifest_file_array = file($manifest_file);
122 
123  foreach ($manifest_file_array as $mfa) {
124  // if (seems_not_utf8($mfa))
125  if (@iconv('UTF-8', 'UTF-8', $mfa) != $mfa) {
126  $needs_convert = true;
127  break;
128  }
129  }
130 
131 
132 
133  // to copy the file we need some extraspace, counted in bytes *2 ... we need 2 copies....
134  $estimated_manifest_filesize = filesize($manifest_file) * 2;
135 
136  // i deactivated this, because it seems to fail on some windows systems (see bug #1795)
137  //$check_disc_free = disk_free_space($this->getDataDirectory()) - $estimated_manifest_filesize;
138  $check_disc_free = 2;
139  }
140 
141 
142  // if $manifest_file needs to be converted to UTF8
143  if ($needs_convert) {
144  // if file exists and enough space left on device
145  if ($check_for_manifest_file && ($check_disc_free > 1)) {
146 
147  // create backup from original
148  if (!copy($manifest_file, $manifest_file . ".old")) {
149  echo "Failed to copy $manifest_file...<br>\n";
150  }
151 
152  // read backupfile, convert each line to utf8, write line to new file
153  // php < 4.3 style
154  $f_write_handler = fopen($manifest_file . ".new", "w");
155  $f_read_handler = fopen($manifest_file . ".old", "r");
156  while (!feof($f_read_handler)) {
157  $zeile = fgets($f_read_handler);
158  //echo mb_detect_encoding($zeile);
159  fputs($f_write_handler, utf8_encode($zeile));
160  }
161  fclose($f_read_handler);
162  fclose($f_write_handler);
163 
164  // copy new utf8-file to imsmanifest.xml
165  if (!copy($manifest_file . ".new", $manifest_file)) {
166  echo "Failed to copy $manifest_file...<br>\n";
167  }
168 
169  if (!@is_file($manifest_file)) {
170  $ilErr->raiseError($this->lng->txt("cont_no_manifest"), $ilErr->WARNING);
171  }
172  } else {
173  // gives out the specific error
174 
175  if (!($check_disc_free > 1)) {
176  $ilErr->raiseError($this->lng->txt("Not enough space left on device!"), $ilErr->MESSAGE);
177  }
178  return;
179  }
180  } else {
181  // check whether file starts with BOM (that confuses some sax parsers, see bug #1795)
182  $hmani = fopen($manifest_file, "r");
183  $start = fread($hmani, 3);
184  if (strtolower(bin2hex($start)) == "efbbbf") {
185  $f_write_handler = fopen($manifest_file . ".new", "w");
186  while (!feof($hmani)) {
187  $n = fread($hmani, 900);
188  fputs($f_write_handler, $n);
189  }
190  fclose($f_write_handler);
191  fclose($hmani);
192 
193  // copy new utf8-file to imsmanifest.xml
194  if (!copy($manifest_file . ".new", $manifest_file)) {
195  echo "Failed to copy $manifest_file...<br>\n";
196  }
197  } else {
198  fclose($hmani);
199  }
200  }
201 
202  //validate the XML-Files in the SCORM-Package
203  if ($_POST["validate"] == "y") {
204  if (!$this->validate($this->getDataDirectory())) {
205  $ilErr->raiseError(
206  "<b>Validation Error(s):</b><br>" . $this->getValidationSummary(),
207  $ilErr->WARNING
208  );
209  }
210  }
211 
212 
213  //check for SCORM 1.2
214  $this->convert_1_2_to_2004($manifest_file);
215 
216  // start SCORM 2004 package parser/importer
217  include_once("./Modules/Scorm2004/classes/ilSCORM13Package.php");
218  $newPack = new ilSCORM13Package();
219  if ($this->getEditable()) {
220  return $newPack->il_importLM(
221  $this,
222  $this->getDataDirectory(),
223  $this->getImportSequencing()
224  );
225  } else {
226  return $newPack->il_import($this->getDataDirectory(), $this->getId(), $DIC["ilias"], $_POST["validate"]);
227  }
228  }
229 
230 
231  public function fixReload()
232  {
233  $out = file_get_contents($this->imsmanifestFile);
234  $check = '/xmlns="http:\/\/www.imsglobal.org\/xsd\/imscp_v1p1"/';
235  $replace = "xmlns=\"http://www.imsproject.org/xsd/imscp_rootv1p1p2\"";
236  $out = preg_replace($check, $replace, $out);
237  file_put_contents($this->imsmanifestFile, $out);
238  }
239 
240 
241  public function convert_1_2_to_2004($manifest)
242  {
243  $ilDB = $this->db;
244  $ilLog = $this->log;
245 
246  ##check manifest-file for version. Check for schemaversion as this is a required element for SCORM 2004
247  ##accept 2004 3rd Edition an CAM 1.3 as valid schemas
248 
249  //set variables
250  $this->packageFolder = $this->getDataDirectory();
251  $this->imsmanifestFile = $manifest;
252  $doc = new DomDocument();
253 
254  //fix reload errors before loading
255  $this->fixReload();
256  $doc->load($this->imsmanifestFile);
257  $elements = $doc->getElementsByTagName("schemaversion");
258  $schema = $elements->item(0)->nodeValue;
259  if (strtolower(trim($schema)) == "cam 1.3" || strtolower(trim($schema)) == "2004 3rd edition" || strtolower(trim($schema)) == "2004 4th edition") {
260  //no conversion
261  $this->converted = false;
262  return true;
263  } else {
264  $this->converted = true;
265  //convert to SCORM 2004
266 
267  //check for broken SCORM 1.2 manifest file (missing organization default-common error in a lot of manifest files)
268  $organizations = $doc->getElementsByTagName("organizations");
269  //first check if organizations is in manifest
270  if ($organizations->item(0) == null) {
271  die("organizations missing in manifest");
272  }
273  $default = $organizations->item(0)->getAttribute("default");
274  if ($default == "" || $default == null) {
275  //lookup identifier
276  $organization = $doc->getElementsByTagName("organization");
277  $ident = $organization->item(0)->getAttribute("identifier");
278  $organizations->item(0)->setAttribute("default", $ident);
279  }
280 
281  //validate the fixed mainfest. If it's still not valid, don't transform an throw error
282 
283 
284  //first copy wrappers
285  $wrapperdir = $this->packageFolder . "/GenericRunTimeWrapper1.0_aadlc";
286  mkdir($wrapperdir);
287  copy(self::WRAPPER_HTML, $wrapperdir . "/GenericRunTimeWrapper.htm");
288  copy(self::WRAPPER_JS, $wrapperdir . "/SCOPlayerWrapper.js");
289 
290  //backup manifestfile
291  $this->backupManifest = $this->packageFolder . "/imsmanifest.xml.back";
292  $ret = copy($this->imsmanifestFile, $this->backupManifest);
293 
294  //transform manifest file
295  $this->totransform = $doc;
296  $ilLog->write("SCORM: about to transform to SCORM 2004");
297 
298  $xsl = new DOMDocument;
299  $xsl->async = false;
300  $xsl->load(self::CONVERT_XSL);
301  $prc = new XSLTProcessor;
302  $r = @$prc->importStyleSheet($xsl);
303 
304  file_put_contents($this->imsmanifestFile, $prc->transformToXML($this->totransform));
305 
306  $ilLog->write("SCORM: Transformation completed");
307  return true;
308  }
309  }
310 
318  public static function _lookupLastAccess($a_obj_id, $a_usr_id)
319  {
320  global $DIC;
321 
322  $ilDB = $DIC->database();
323 
324  $result = $ilDB->queryF(
325  '
326  SELECT MAX(c_timestamp) last_access
327  FROM cmi_node, cp_node
328  WHERE cmi_node.cp_node_id = cp_node.cp_node_id
329  AND cp_node.slm_id = %s
330  AND user_id = %s
331  GROUP BY c_timestamp',
332  array('integer', 'integer'),
333  array($a_obj_id, $a_usr_id)
334  );
335  if ($ilDB->numRows($result)) {
336  $row = $ilDB->fetchAssoc($result);
337  return $row["last_access"];
338  }
339 
340  return "";
341  }
342 
346  // function getTrackedUsers($a_search)
347  // {
348  // global $DIC;
349  // $ilUser = $DIC['ilUser'];
350  // $ilDB = $DIC['ilDB'];
351  // $ilUser = $DIC['ilUser'];
352 
353  // $sco_set = $ilDB->queryF('
354  // SELECT DISTINCT user_id,MAX(c_timestamp) last_access
355  // FROM cmi_node, cp_node
356  // WHERE cmi_node.cp_node_id = cp_node.cp_node_id
357  // AND cp_node.slm_id = %s
358  // GROUP BY user_id',
359  // array('integer'),
360  // array($this->getId()));
361 
362  // $items = array();
363  // $temp = array();
364 
365  // while($sco_rec = $ilDB->fetchAssoc($sco_set))
366  // {
367  // $name = ilObjUser::_lookupName($sco_rec["user_id"]);
368  // if ($sco_rec['last_access'] != 0) {
369  // // $sco_rec['last_access'] = $sco_rec['last_access'];
370  // } else {
371  // $sco_rec['last_access'] = "";
372  // }
373  // if (ilObject::_exists($sco_rec['user_id']) && ilObject::_lookUpType($sco_rec['user_id'])=="usr" ) {
374  // $user = new ilObjUser($sco_rec['user_id']);
375  // $temp = array("user_full_name" => $name["lastname"].", ".
376  // $name["firstname"]." [".ilObjUser::_lookupLogin($sco_rec["user_id"])."]",
377  // "user_id" => $sco_rec["user_id"],"last_access" => $sco_rec['last_access'],
378  // "version"=> $this->getModuleVersionForUser($sco_rec["user_id"]),
379  // "attempts" => $this->getAttemptsForUser($sco_rec["user_id"]),
380  // "username" => $user->getLastname().", ".$user->getFirstname()
381  // );
382  // if ($a_search != "" && (strpos(strtolower($user->getLastname()), strtolower($a_search)) !== false || strpos(strtolower($user->getFirstname()), strtolower($a_search)) !== false ) ) {
383  // $items[] = $temp;
384  // } else if ($a_search == "") {
385  // $items[] = $temp;
386  // }
387  // }
388  // }
389 
390  // return $items;
391  // }
392 
393  public function deleteTrackingDataOfUsers($a_users)
394  {
395  $ilDB = $this->db;
396  include_once("./Modules/Scorm2004/classes/class.ilSCORM2004DeleteData.php");
397  include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
398  include_once("./Services/Tracking/classes/class.ilChangeEvent.php");
400 
401  foreach ($a_users as $user) {
403  ilLPStatusWrapper::_updateStatus($this->getId(), $user);
404  }
405  }
406 
407 
411  public function getTrackedItems()
412  {
414  $ilDB = $this->db;
416 
417  $sco_set = $ilDB->queryF(
418  '
419  SELECT DISTINCT cmi_node.cp_node_id id
420  FROM cp_node, cmi_node
421  WHERE slm_id = %s
422  AND cp_node.cp_node_id = cmi_node.cp_node_id
423  ORDER BY cmi_node.cp_node_id ',
424  array('integer'),
425  array($this->getId())
426  );
427 
428  $items = array();
429 
430  while ($sco_rec = $ilDB->fetchAssoc($sco_set)) {
431  $item['id'] = $sco_rec["id"];
432  $item['title'] = self::_lookupItemTitle($sco_rec["id"]);
433  $items[count($items)] = $item;
434  }
435  return $items;
436  }
437 
438 
439  public function getTrackingDataAgg($a_user_id, $raw = false)
440  {
441  $ilDB = $this->db;
442 
443  $scos = array();
444  $data = array();
445  //get all SCO's of this object
446 
447  $val_set = $ilDB->queryF(
448  'SELECT cp_node_id FROM cp_node
449  WHERE nodename = %s
450  AND cp_node.slm_id = %s',
451  array('text', 'integer'),
452  array('item',$this->getId())
453  );
454  while ($val_rec = $ilDB->fetchAssoc($val_set)) {
455  array_push($scos, $val_rec['cp_node_id']);
456  }
457 
458  foreach ($scos as $sco) {
459  $data_set = $ilDB->queryF(
460  '
461  SELECT c_timestamp last_access, total_time, success_status, completion_status,
462  c_raw, scaled, cp_node_id
463  FROM cmi_node
464  WHERE cp_node_id = %s
465  AND user_id = %s',
466  array('integer','integer'),
467  array($sco,$a_user_id)
468  );
469 
470  while ($data_rec = $ilDB->fetchAssoc($data_set)) {
471  if ($data_rec["success_status"] != "" && $data_rec["success_status"] != "unknown") {
472  $status = $data_rec["success_status"];
473  } else {
474  if ($data_rec["completion_status"] == "") {
475  $status = "unknown";
476  } else {
477  $status = $data_rec["completion_status"];
478  }
479  }
480  if (!$raw) {
481  $time = ilDatePresentation::secondsToString(self::_ISODurationToCentisec($data_rec["total_time"]) / 100);
482  $score = "";
483  if ($data_rec["c_raw"] != null) {
484  $score = $data_rec["c_raw"];
485  if ($data_rec["scaled"] != null) {
486  $score .= " = ";
487  }
488  }
489  if ($data_rec["scaled"] != null) {
490  $score .= ($data_rec["scaled"] * 100) . "%";
491  }
492  $title = self::_lookupItemTitle($data_rec["cp_node_id"]);
493  $last_access = ilDatePresentation::formatDate(new ilDateTime($data_rec['last_access'], IL_CAL_DATETIME));
494  $data[] = array("sco_id" => $data_rec["cp_node_id"],
495  "score" => $score, "time" => $time, "status" => $status,"last_access" => $last_access,"title" => $title);
496  } else {
497  $data_rec["total_time"] = self::_ISODurationToCentisec($data_rec["total_time"]) / 100;
498  $data[$data_rec["cp_node_id"]] = $data_rec;
499  }
500  }
501  }
502 
503 
504  return $data;
505  }
506 
510  public function getAttemptsForUser($a_user_id)
511  {
512  $ilDB = $this->db;
513  $val_set = $ilDB->queryF(
514  'SELECT package_attempts FROM sahs_user WHERE user_id = %s AND obj_id = %s',
515  array('integer','integer'),
516  array($a_user_id, $this->getId())
517  );
518 
519  $val_rec = $ilDB->fetchAssoc($val_set);
520 
521  if ($val_rec["package_attempts"] == null) {
522  $val_rec["package_attempts"] = "";
523  }
524 
525  return $val_rec["package_attempts"];
526  }
527 
528 
532  public function getModuleVersionForUser($a_user_id)
533  {
534  $ilDB = $this->db;
535  $val_set = $ilDB->queryF(
536  'SELECT module_version FROM sahs_user WHERE user_id = %s AND obj_id = %s',
537  array('integer','integer'),
538  array($a_user_id, $this->getId())
539  );
540 
541  $val_rec = $ilDB->fetchAssoc($val_set);
542 
543  if ($val_rec["module_version"] == null) {
544  $val_rec["module_version"] = "";
545  }
546  return $val_rec["module_version"];
547  }
548 
549 
550  // function exportSelected($a_exportall = 0, $a_user = array())
551  // {
552  // include_once("./Modules/Scorm2004/classes/class.ilSCORM2004TrackingItemsExport.php");
553  // ilSCORM2004TrackingItemsExport::exportSelected($a_exportall = 0, $a_user = array());
554  // }
555 
556 
557 
558  public function importSuccess($a_file)
559  {
560  $ilDB = $this->db;
562  include_once("./Services/Tracking/classes/class.ilLPStatus.php");
563  $scos = array();
564  //get all SCO's of this object ONLY RELEVANT!
565  include_once './Services/Object/classes/class.ilObjectLP.php';
566  $olp = ilObjectLP::getInstance($this->getId());
567  $collection = $olp->getCollectionInstance();
568  if ($collection) {
569  $scos = $collection->getItems();
570  }
571 
572  $fhandle = fopen($a_file, "r");
573 
574  $obj_id = $this->getID();
575  $users = array();
576  $usersToDelete = array();
577  $fields = fgetcsv($fhandle, 4096, ';');
578  while (($csv_rows = fgetcsv($fhandle, 4096, ";")) !== false) {
579  $data = array_combine($fields, $csv_rows);
580  //no check the format - sufficient to import users
581  if ($data["Login"]) {
582  $user_id = $this->get_user_id($data["Login"]);
583  }
584  if ($data["login"]) {
585  $user_id = $this->get_user_id($data["login"]);
586  }
587  //add mail in future
588  if ($data["user"] && is_numeric($data["user"])) {
589  $user_id = $data["user"];
590  }
591  if ($user_id > 0) {
592  $last_access = ilUtil::now();
593  if ($data['Date']) {
594  $date_ex = explode('.', $data['Date']);
595  $last_access = implode('-', array($date_ex[2], $date_ex[1], $date_ex[0]));
596  }
597  if ($data['LastAccess']) {
598  $last_access = $data['LastAccess'];
599  }
600 
602 
603  if ($data["Status"]) {
604  if (is_numeric($data["Status"])) {
605  $status = $data["Status"];
606  } elseif ($data["Status"] == ilLPStatus::LP_STATUS_NOT_ATTEMPTED) {
608  } elseif ($data["Status"] == ilLPStatus::LP_STATUS_IN_PROGRESS) {
610  } elseif ($data["Status"] == ilLPStatus::LP_STATUS_FAILED) {
612  }
613  }
614  $attempts = null;
615  if ($data["Attempts"]) {
616  $attempts = $data["Attempts"];
617  }
618 
619  $percentage_completed = 0;
620  if ($status == ilLPStatus::LP_STATUS_COMPLETED_NUM) {
621  $percentage_completed = 100;
622  } elseif ($data['percentageCompletedSCOs']) {
623  $percentage_completed = $data['percentageCompletedSCOs'];
624  }
625 
626  $sco_total_time_sec = null;
627  if ($data['SumTotal_timeSeconds']) {
628  $sco_total_time_sec = $data['SumTotal_timeSeconds'];
629  }
630 
631  if ($status == ilLPStatus::LP_STATUS_NOT_ATTEMPTED) {
632  $usersToDelete[] = $user_id;
633  } else {
634  $this->importSuccessForSahsUser($user_id, $last_access, $status, $attempts, $percentage_completed, $sco_total_time_sec);
635  $users[] = $user_id;
636  }
637 
638  if ($status == ilLPStatus::LP_STATUS_COMPLETED_NUM) {
639  foreach ($scos as $sco_id) {
640  $res = $ilDB->queryF(
641  '
642  SELECT completion_status, success_status, user_id FROM cmi_node WHERE cp_node_id = %s AND user_id = %s',
643  array('integer','integer'),
644  array($sco_id,$user_id)
645  );
646 
647  if (!$ilDB->numRows($res)) {
648  $nextId = $ilDB->nextId('cmi_node');
649  $val_set = $ilDB->manipulateF(
650  'INSERT INTO cmi_node
651  (cp_node_id,user_id,completion_status,c_timestamp,cmi_node_id)
652  VALUES(%s,%s,%s,%s,%s)',
653  array('integer','integer','text','timestamp','integer'),
654  array($sco_id,$user_id,'completed',$last_access,$nextId)
655  );
656  } else {
657  $doUpdate = false;
658  while ($row = $ilDB->fetchAssoc($res)) {
659  if (($row["completion_status"] == "completed" && $row["success_status"] != "failed") || $row["success_status"] == "passed") {
660  if ($doUpdate != true) {
661  $doUpdate = false;
662  } //note for issue if there are 2 entries for same sco_id
663  } else {
664  $doUpdate = true;
665  }
666  }
667  if ($doUpdate == true) {
668  $ilDB->update(
669  'cmi_node',
670  array(
671  'completion_status' => array('text', 'completed'),
672  'success_status' => array('text', ''),
673  'suspend_data' => array('text', ''),
674  'c_timestamp' => array('timestamp', $last_access)
675  ),
676  array(
677  'user_id' => array('integer', $user_id),
678  'cp_node_id' => array('integer', $sco_id)
679  )
680  );
681  }
682  }
683  }
684  }
685  } else {
686  //echo "Warning! User $csv_rows[0] does not exist in ILIAS. Data for this user was skipped.\n";
687  }
688  }
689 
690  if (count($usersToDelete) > 0) {
691  // include_once("./Services/Tracking/classes/class.ilLPMarks.php");
692  // ilLPMarks::_deleteForUsers($this->getId(), $usersToDelete);
693  $this->deleteTrackingDataOfUsers($usersToDelete);
694  }
695  include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
697 
698  return 0;
699  }
700 
707  public static function _ISODurationToCentisec($str)
708  {
709  $aV = array(0, 0, 0, 0, 0, 0);
710  $bErr = false;
711  $bTFound = false;
712  if (strpos($str, "P") != 0) {
713  $bErr = true;
714  }
715  if (!$bErr) {
716  $aT = array("Y", "M", "D", "H", "M", "S");
717  $p = 0;
718  $i = 0;
719  $str = substr($str, 1);
720  for ($i = 0; $i < count($aT); $i++) {
721  if (strpos($str, "T") === 0) {
722  $str = substr($str, 1);
723  $i = max($i, 3);
724  $bTFound = true;
725  }
726  $p = strpos($str, $aT[$i]);
727 
728  if ($p > -1) {
729  if ($i == 1 && strpos($str, "T") > -1 && strpos($str, "T") < $p) {
730  continue;
731  }
732  if ($aT[$i] == "S") {
733  $aV[$i] = substr($str, 0, $p);
734  } else {
735  $aV[$i] = intval(substr($str, 0, $p));
736  }
737  if (!is_numeric($aV[$i])) {
738  $bErr = true;
739  break;
740  } elseif ($i > 2 && !$bTFound) {
741  $bErr = true;
742  break;
743  }
744  $str = substr($str, $p + 1);
745  }
746  }
747  if (!$bErr && strlen($str) != 0) {
748  $bErr = true;
749  }
750  }
751 
752  if ($bErr) {
753  return;
754  }
755  return $aV[0] * 3155760000 + $aV[1] * 262980000 + $aV[2] * 8640000 + $aV[3] * 360000 + $aV[4] * 6000 + round($aV[5] * 100);
756  }
757 
758  public static function getQuantityOfSCOs(int $a_slm_id)
759  {
760  global $DIC;
761  $val_set = $DIC->database()->queryF(
762  '
763  SELECT distinct(cp_node.cp_node_id) FROM cp_node,cp_resource,cp_item
764  WHERE cp_item.cp_node_id = cp_node.cp_node_id
765  AND cp_item.resourceid = cp_resource.id
766  AND scormtype = %s
767  AND nodename = %s
768  AND cp_node.slm_id = %s ',
769  array('text','text','integer'),
770  array('sco','item',$a_slm_id)
771  );
772  return $DIC->database()->numRows($val_set);
773  }
774 
775  public function getCourseCompletionForUser($a_user)
776  {
777  $ilDB = $this->db;
779 
780  $scos = array();
781  //get all SCO's of this object
782 
783  $val_set = $ilDB->queryF(
784  '
785  SELECT cp_node.cp_node_id FROM cp_node,cp_resource,cp_item
786  WHERE cp_item.cp_node_id = cp_node.cp_node_id
787  AND cp_item.resourceid = cp_resource.id
788  AND scormtype = %s
789  AND nodename = %s
790  AND cp_node.slm_id = %s ',
791  array('text','text','integer'),
792  array('sco','item',$this->getId())
793  );
794 
795  while ($val_rec = $ilDB->fetchAssoc($val_set)) {
796  array_push($scos, $val_rec['cp_node_id']);
797  }
798 
799 
800  $scos_c = $scos;
801  //copy SCO_array
802  //check if all SCO's are completed
803  for ($i = 0;$i < count($scos);$i++) {
804  $val_set = $ilDB->queryF(
805  '
806  SELECT * FROM cmi_node
807  WHERE (user_id= %s
808  AND cp_node_id= %s
809  AND (completion_status=%s OR success_status=%s))',
810  array('integer','integer','text', 'text'),
811  array($a_user,$scos[$i],'completed','passed')
812  );
813 
814  if ($ilDB->numRows($val_set) > 0) {
815  //delete from array
816  $key = array_search($scos[$i], $scos_c);
817  unset($scos_c[$key]);
818  }
819  }
820  //check for completion
821  if (count($scos_c) == 0) {
822  $completion = true;
823  } else {
824  $completion = false;
825  }
826  return $completion;
827  }
828 
835  public static function _getCourseCompletionForUser($a_id, $a_user)
836  {
837  global $DIC;
838 
839  $ilDB = $DIC->database();
840  $ilUser = $DIC->user();
841  $scos = array();
842  //get all SCO's of the object
843 
844  $val_set = $ilDB->queryF(
845  '
846  SELECT cp_node.cp_node_id FROM cp_node,cp_resource,cp_item
847  WHERE cp_item.cp_node_id = cp_node.cp_node_id
848  AND cp_item.resourceid = cp_resource.id
849  AND scormtype = %s
850  AND nodename = %s
851  AND cp_node.slm_id = %s',
852  array('text','text','integer'),
853  array('sco' ,'item',$a_id)
854  );
855  while ($val_rec = $ilDB->fetchAssoc($val_set)) {
856  array_push($scos, $val_rec['cp_node_id']);
857  }
858 
859  $scos_c = $scos;
860  //copy SCO_array
861  //check if all SCO's are completed
862  for ($i = 0;$i < count($scos);$i++) {
863  $val_set = $ilDB->queryF(
864  '
865  SELECT * FROM cmi_node
866  WHERE (user_id= %s
867  AND cp_node_id= %s
868  AND (completion_status = %s OR success_status = %s))',
869  array('integer','integer','text','text'),
870  array($a_user,$scos[$i],'completed','passed')
871  );
872 
873  if ($ilDB->numRows($val_set) > 0) {
874  //delete from array
875  $key = array_search($scos[$i], $scos_c);
876  unset($scos_c[$key]);
877  }
878  }
879  //check for completion
880  if (count($scos_c) == 0) {
881  $completion = true;
882  } else {
883  $completion = false;
884  }
885  return $completion;
886  }
887 
895  public static function _getUniqueScaledScoreForUser($a_id, $a_user)
896  {
897  global $DIC;
898 
899  $ilDB = $DIC->database();
900  $ilUser = $DIC->user();
901  $scos = array();
902 
903  $val_set = $ilDB->queryF(
904  "SELECT cp_node.cp_node_id FROM cp_node,cp_resource,cp_item WHERE" .
905  " cp_item.cp_node_id=cp_node.cp_node_id AND cp_item.resourceId = cp_resource.id AND scormType='sco' AND nodeName='item' AND cp_node.slm_id = %s GROUP BY cp_node.cp_node_id",
906  array('integer'),
907  array($a_id)
908  );
909  while ($val_rec = $ilDB->fetchAssoc($val_set)) {
910  array_push($scos, $val_rec['cp_node_id']);
911  }
912  $set = 0; //numbers of SCO that set cmi.score.scaled
913  $scaled = null;
914  for ($i = 0;$i < count($scos);$i++) {
915  $val_set = $ilDB->queryF(
916  "SELECT scaled FROM cmi_node WHERE (user_id = %s AND cp_node_id = %s)",
917  array('integer', 'integer'),
918  array($a_user, $scos[$i])
919  );
920  if ($val_set->numRows() > 0) {
921  $val_rec = $ilDB->fetchAssoc($val_set);
922  if ($val_rec['scaled'] != null) {
923  $set++;
924  $scaled = $val_rec['scaled'];
925  }
926  }
927  }
928  $retVal = ($set == 1) ? $scaled : null ;
929  return $retVal;
930  }
931 
937  public static function _getTrackingItems($a_obj_id)
938  {
939  global $DIC;
940 
941  $ilDB = $DIC->database();
942 
943 
944  $item_set = $ilDB->queryF(
945  '
946  SELECT cp_item.* FROM cp_node, cp_item WHERE slm_id = %s
947  AND cp_node.cp_node_id = cp_item.cp_node_id
948  ORDER BY cp_node.cp_node_id ',
949  array('integer'),
950  array($a_obj_id)
951  );
952 
953  $items = array();
954  while ($item_rec = $ilDB->fetchAssoc($item_set)) {
955  $s2 = $ilDB->queryF(
956  '
957  SELECT cp_resource.* FROM cp_node, cp_resource
958  WHERE slm_id = %s
959  AND cp_node.cp_node_id = cp_resource.cp_node_id
960  AND cp_resource.id = %s ',
961  array('integer','text'),
962  array($a_obj_id,$item_rec["resourceid"])
963  );
964 
965 
966  if ($res = $ilDB->fetchAssoc($s2)) {
967  if ($res["scormtype"] == "sco") {
968  $items[] = array("id" => $item_rec["cp_node_id"],
969  "title" => $item_rec["title"]);
970  }
971  }
972  }
973 
974  return $items;
975  }
976 
977  public static function _getStatus($a_obj_id, $a_user_id)
978  {
979  global $DIC;
980 
981  $ilDB = $DIC->database();
982 
983  $status_set = $ilDB->queryF(
984  '
985  SELECT * FROM cmi_gobjective
986  WHERE scope_id = %s
987  AND objective_id = %s
988  AND user_id = %s',
989  array('integer','text','integer'),
990  array($a_obj_id,'-course_overall_status-',$a_user_id)
991  );
992 
993  if ($status_rec = $ilDB->fetchAssoc($status_set)) {
994  return $status_rec["status"];
995  }
996 
997  return false;
998  }
999 
1000  public static function _getSatisfied($a_obj_id, $a_user_id)
1001  {
1002  global $DIC;
1003 
1004  $ilDB = $DIC->database();
1005 
1006 
1007  $status_set = $ilDB->queryF(
1008  '
1009  SELECT * FROM cmi_gobjective
1010  WHERE scope_id = %s
1011  AND objective_id = %s
1012  AND user_id = %s',
1013  array('integer','text','integer'),
1014  array($a_obj_id,'-course_overall_status-',$a_user_id)
1015  );
1016 
1017  if ($status_rec = $ilDB->fetchAssoc($status_set)) {
1018  return $status_rec["satisfied"];
1019  }
1020 
1021  return false;
1022  }
1023 
1024  public static function _getMeasure($a_obj_id, $a_user_id)
1025  {
1026  global $DIC;
1027 
1028  $ilDB = $DIC->database();
1029 
1030  $status_set = $ilDB->queryF(
1031  '
1032  SELECT * FROM cmi_gobjective
1033  WHERE scope_id = %s
1034  AND objective_id = %s
1035  AND user_id = %s',
1036  array('integer','text','integer'),
1037  array($a_obj_id,'-course_overall_status-',$a_user_id)
1038  );
1039 
1040  if ($status_rec = $ilDB->fetchAssoc($status_set)) {
1041  return $status_rec["measure"];
1042  }
1043 
1044  return false;
1045  }
1046 
1047  public static function _lookupItemTitle($a_node_id)
1048  {
1049  global $DIC;
1050 
1051  $ilDB = $DIC->database();
1052 
1053  $r = $ilDB->queryF(
1054  '
1055  SELECT * FROM cp_item
1056  WHERE cp_node_id = %s',
1057  array('integer'),
1058  array($a_node_id)
1059  );
1060 
1061  if ($i = $ilDB->fetchAssoc($r)) {
1062  return $i["title"];
1063  }
1064  return "";
1065  }
1066 
1070  public function createScorm2004Tree()
1071  {
1072  include_once("./Modules/Scorm2004/classes/class.ilSCORM2004Tree.php");
1073  $this->slm_tree = new ilSCORM2004Tree($this->getId());
1074 
1075  //$this->slm_tree = new ilTree($this->getId());
1076  //$this->slm_tree->setTreeTablePK("slm_id");
1077  //$this->slm_tree->setTableNames('sahs_sc13_tree', 'sahs_sc13_tree_node');
1078  $this->slm_tree->addTree($this->getId(), 1);
1079 
1080  //add seqinfo for rootNode
1081  include_once("./Modules/Scorm2004/classes/seq_editor/class.ilSCORM2004Sequencing.php");
1082  $seq_info = new ilSCORM2004Sequencing($this->getId(), true);
1083  $seq_info->insert();
1084  }
1085 
1086  public function getTree()
1087  {
1088  $this->slm_tree = new ilTree($this->getId());
1089  $this->slm_tree->setTreeTablePK("slm_id");
1090  $this->slm_tree->setTableNames('sahs_sc13_tree', 'sahs_sc13_tree_node');
1091  return $this->slm_tree;
1092  }
1093 
1094  public function getSequencingSettings()
1095  {
1096  $ilTabs = $this->tabs;
1097  $ilTabs->setTabActive("sequencing");
1098 
1099  include_once("./Modules/Scorm2004/classes/seq_editor/class.ilSCORM2004Sequencing.php");
1100  $control_settings = new ilSCORM2004Sequencing($this->getId(), true);
1101 
1102  return $control_settings;
1103  }
1104 
1105  public function updateSequencingSettings()
1106  {
1107  include_once("./Modules/Scorm2004/classes/seq_editor/class.ilSCORM2004Sequencing.php");
1108 
1109  $control_settings = new ilSCORM2004Sequencing($this->getId(), true);
1110  $control_settings->setChoice(ilUtil::yn2tf($_POST["choice"]));
1111  $control_settings->setFlow(ilUtil::yn2tf($_POST["flow"]));
1112  $control_settings->setForwardOnly(ilUtil::yn2tf($_POST["forwardonly"]));
1113  $control_settings->insert();
1114 
1115  return true;
1116  }
1117 
1126  public function executeDragDrop($source_id, $target_id, $first_child, $as_subitem = false, $movecopy = "move")
1127  {
1128  $this->slm_tree = new ilTree($this->getId());
1129  $this->slm_tree->setTableNames('sahs_sc13_tree', 'sahs_sc13_tree_node');
1130  $this->slm_tree->setTreeTablePK("slm_id");
1131 
1132  require_once("./Modules/Scorm2004/classes/class.ilSCORM2004NodeFactory.php");
1133 
1134  $source_obj = ilSCORM2004NodeFactory::getInstance($this, $source_id, true);
1135  //$source_obj->setLMId($this->getId());
1136 
1137  if (!$first_child) {
1138  $target_obj = ilSCORM2004NodeFactory::getInstance($this, $target_id, true);
1139  //$target_obj->setLMId($this->getId());
1140  $target_parent = $this->slm_tree->getParentId($target_id);
1141  }
1142  //echo "-".$source_obj->getType()."-";
1143  // handle pages
1144  if ($source_obj->getType() == "page") {
1145  if ($this->slm_tree->isInTree($source_obj->getId())) {
1146  $node_data = $this->slm_tree->getNodeData($source_obj->getId());
1147 
1148  // cut on move
1149  if ($movecopy == "move") {
1150  $parent_id = $this->slm_tree->getParentId($source_obj->getId());
1151  $this->slm_tree->deleteTree($node_data);
1152 
1153  // write history entry
1154 /* require_once("./Services/History/classes/class.ilHistory.php");
1155  ilHistory::_createEntry($source_obj->getId(), "cut",
1156  array(ilLMObject::_lookupTitle($parent_id), $parent_id),
1157  $this->getType().":pg");
1158  ilHistory::_createEntry($parent_id, "cut_page",
1159  array(ilLMObject::_lookupTitle($source_obj->getId()), $source_obj->getId()),
1160  $this->getType().":st");
1161 */
1162  }
1163  /* else // this is not implemented here
1164  {
1165  // copy page
1166  $new_page =& $source_obj->copy();
1167  $source_id = $new_page->getId();
1168  $source_obj =& $new_page;
1169  }
1170  */
1171 
1172  // paste page
1173  if (!$this->slm_tree->isInTree($source_obj->getId())) {
1174  if ($first_child) { // as first child
1175  $target_pos = IL_FIRST_NODE;
1176  $parent = $target_id;
1177  } elseif ($as_subitem) { // as last child
1178  $parent = $target_id;
1179  $target_pos = IL_FIRST_NODE;
1180  $pg_childs = $this->slm_tree->getChildsByType($parent, "page");
1181  if (count($pg_childs) != 0) {
1182  $target_pos = $pg_childs[count($pg_childs) - 1]["obj_id"];
1183  }
1184  } else { // at position
1185  $target_pos = $target_id;
1186  $parent = $target_parent;
1187  }
1188 
1189  // insert page into tree
1190  $this->slm_tree->insertNode(
1191  $source_obj->getId(),
1192  $parent,
1193  $target_pos
1194  );
1195 
1196  // write history entry
1197 /* if ($movecopy == "move")
1198  {
1199  // write history comments
1200  include_once("./Services/History/classes/class.ilHistory.php");
1201  ilHistory::_createEntry($source_obj->getId(), "paste",
1202  array(ilLMObject::_lookupTitle($parent), $parent),
1203  $this->getType().":pg");
1204  ilHistory::_createEntry($parent, "paste_page",
1205  array(ilLMObject::_lookupTitle($source_obj->getId()), $source_obj->getId()),
1206  $this->getType().":st");
1207  }
1208 */
1209  }
1210  }
1211  }
1212 
1213  // handle scos
1214  if ($source_obj->getType() == "sco" || $source_obj->getType() == "ass") {
1215  //echo "2";
1216  $source_node = $this->slm_tree->getNodeData($source_id);
1217  $subnodes = $this->slm_tree->getSubtree($source_node);
1218 
1219  // check, if target is within subtree
1220  foreach ($subnodes as $subnode) {
1221  if ($subnode["obj_id"] == $target_id) {
1222  return;
1223  }
1224  }
1225 
1226  $target_pos = $target_id;
1227 
1228  if ($first_child) { // as first sco
1229  $target_pos = IL_FIRST_NODE;
1230  $target_parent = $target_id;
1231 
1232  $pg_childs = $this->slm_tree->getChildsByType($target_parent, "page");
1233  if (count($pg_childs) != 0) {
1234  $target_pos = $pg_childs[count($pg_childs) - 1]["obj_id"];
1235  }
1236  } elseif ($as_subitem) { // as last sco
1237  $target_parent = $target_id;
1238  $target_pos = IL_FIRST_NODE;
1239  $childs = $this->slm_tree->getChilds($target_parent);
1240  if (count($childs) != 0) {
1241  $target_pos = $childs[count($childs) - 1]["obj_id"];
1242  }
1243  }
1244 
1245  // delete source tree
1246  if ($movecopy == "move") {
1247  $this->slm_tree->deleteTree($source_node);
1248  }
1249  /* else
1250  {
1251  // copy chapter (incl. subcontents)
1252  $new_chapter =& $source_obj->copy($this->slm_tree, $target_parent, $target_pos);
1253  }
1254  */
1255 
1256  if (!$this->slm_tree->isInTree($source_id)) {
1257  $this->slm_tree->insertNode($source_id, $target_parent, $target_pos);
1258 
1259  // insert moved tree
1260  if ($movecopy == "move") {
1261  foreach ($subnodes as $node) {
1262  if ($node["obj_id"] != $source_id) {
1263  $this->slm_tree->insertNode($node["obj_id"], $node["parent"]);
1264  }
1265  }
1266  }
1267  }
1268 
1269  // check the tree
1270 // $this->checkTree();
1271  }
1272 
1273  // handle chapters
1274  if ($source_obj->getType() == "chap") {
1275  //echo "2";
1276  $source_node = $this->slm_tree->getNodeData($source_id);
1277  $subnodes = $this->slm_tree->getSubtree($source_node);
1278 
1279  // check, if target is within subtree
1280  foreach ($subnodes as $subnode) {
1281  if ($subnode["obj_id"] == $target_id) {
1282  return;
1283  }
1284  }
1285 
1286  $target_pos = $target_id;
1287 
1288  if ($first_child) { // as first chapter
1289  $target_pos = IL_FIRST_NODE;
1290  $target_parent = $target_id;
1291 
1292  //$sco_childs = $this->slm_tree->getChildsByType($target_parent, "sco");
1293  //if (count($sco_childs) != 0)
1294  //{
1295  // $target_pos = $sco_childs[count($sco_childs) - 1]["obj_id"];
1296  //}
1297  } elseif ($as_subitem) { // as last chapter
1298  $target_parent = $target_id;
1299  $target_pos = IL_FIRST_NODE;
1300  $childs = $this->slm_tree->getChilds($target_parent);
1301  if (count($childs) != 0) {
1302  $target_pos = $childs[count($childs) - 1]["obj_id"];
1303  }
1304  }
1305 
1306  // delete source tree
1307  if ($movecopy == "move") {
1308  $this->slm_tree->deleteTree($source_node);
1309  }
1310  /* else
1311  {
1312  // copy chapter (incl. subcontents)
1313  $new_chapter =& $source_obj->copy($this->slm_tree, $target_parent, $target_pos);
1314  }
1315  */
1316 
1317  if (!$this->slm_tree->isInTree($source_id)) {
1318  $this->slm_tree->insertNode($source_id, $target_parent, $target_pos);
1319 
1320  // insert moved tree
1321  if ($movecopy == "move") {
1322  foreach ($subnodes as $node) {
1323  if ($node["obj_id"] != $source_id) {
1324  $this->slm_tree->insertNode($node["obj_id"], $node["parent"]);
1325  }
1326  }
1327  }
1328  }
1329 
1330  // check the tree
1331 // $this->checkTree();
1332  }
1333 
1334  // $this->checkTree();
1335  }
1336 
1337  public function getExportFiles()
1338  {
1339  $file = array();
1340 
1341  require_once("./Modules/Scorm2004/classes/class.ilSCORM2004Export.php");
1342 
1343  $export = new ilSCORM2004Export($this);
1344  foreach ($export->getSupportedExportTypes() as $type) {
1345  $dir = $export->getExportDirectoryForType($type);
1346  // quit if import dir not available
1347  if (!@is_dir($dir) or !is_writeable($dir)) {
1348  continue;
1349  }
1350  // open directory
1351  $cdir = dir($dir);
1352 
1353  // get files and save the in the array
1354  while ($entry = $cdir->read()) {
1355  if ($entry != "." and
1356  $entry != ".." and
1357  (
1358  preg_match("~^[0-9]{10}_{2}[0-9]+_{2}(" . $this->getType() . "_)*[0-9]+\.zip\$~", $entry) or
1359  preg_match("~^[0-9]{10}_{2}[0-9]+_{2}(" . $this->getType() . "_)*[0-9]+\.pdf\$~", $entry) or
1360  preg_match("~^[0-9]{10}_{2}[0-9]+_{2}(" . $this->getType() . "_)*[0-9]+\.iso\$~", $entry)
1361  )) {
1362  $file[$entry . $type] = array("type" => $type, "file" => $entry,
1363  "size" => filesize($dir . "/" . $entry));
1364  }
1365  }
1366 
1367  // close import directory
1368  $cdir->close();
1369  }
1370 
1371  // sort files
1372  ksort($file);
1373  reset($file);
1374  return $file;
1375  }
1376 
1380  public function exportScorm($a_inst, $a_target_dir, $ver, &$expLog)
1381  {
1382  $a_xml_writer = new ilXmlWriter;
1383 
1384  // export metadata
1385  $this->exportXMLMetaData($a_xml_writer);
1386  $metadata_xml = $a_xml_writer->xmlDumpMem(false);
1387  $a_xml_writer->_XmlWriter;
1388 
1389  $xsl = file_get_contents("./Modules/Scorm2004/templates/xsl/metadata.xsl");
1390  $args = array( '/_xml' => $metadata_xml , '/_xsl' => $xsl );
1391  $xh = xslt_create();
1392  $output = xslt_process($xh, "arg:/_xml", "arg:/_xsl", null, $args, null);
1393  xslt_free($xh);
1394  file_put_contents($a_target_dir . '/indexMD.xml', $output);
1395 
1396  // export glossary
1397  if ($this->getAssignedGlossary() != 0) {
1398  ilUtil::makeDir($a_target_dir . "/glossary");
1399  include_once("./Modules/Glossary/classes/class.ilObjGlossary.php");
1400  include_once("./Modules/Glossary/classes/class.ilGlossaryExport.php");
1401  $glo_xml_writer = new ilXmlWriter();
1402 
1403  $glo_xml_writer->xmlSetDtdDef("<!DOCTYPE ContentObject SYSTEM \"http://www.ilias.de/download/dtd/ilias_co_3_7.dtd\">");
1404  // set xml header
1405  $glo_xml_writer->xmlHeader();
1406  $glos = new ilObjGlossary($this->getAssignedGlossary(), false);
1407  //$glos->exportHTML($a_target_dir."/glossary", $expLog);
1408  $glos_export = new ilGlossaryExport($glos, "xml");
1409  $glos->exportXML($glo_xml_writer, $glos_export->getInstId(), $a_target_dir . "/glossary", $expLog);
1410  $glo_xml_writer->xmlDumpFile($a_target_dir . "/glossary/glossary.xml");
1411  $glo_xml_writer->_XmlWriter;
1412  }
1413 
1414  $a_xml_writer = new ilXmlWriter;
1415  // set dtd definition
1416  $a_xml_writer->xmlSetDtdDef("<!DOCTYPE ContentObject SYSTEM \"http://www.ilias.de/download/dtd/ilias_co_3_7.dtd\">");
1417 
1418  // set generated comment
1419  $a_xml_writer->xmlSetGenCmt("Export of ILIAS Content Module " . $this->getId() . " of installation " . $a_inst . ".");
1420 
1421  // set xml header
1422  $a_xml_writer->xmlHeader();
1423 
1424  $a_xml_writer->xmlStartTag("ContentObject", array("Type" => "SCORM2004LearningModule"));
1425 
1426  // MetaData
1427  $this->exportXMLMetaData($a_xml_writer);
1428 
1429  $this->exportXMLStructureObjects($a_xml_writer, $a_inst, $expLog);
1430 
1431  // SCO Objects
1432  $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Sco Objects");
1433  $this->exportXMLScoObjects($a_inst, $a_target_dir, $ver, $expLog);
1434  $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Sco Objects");
1435 
1436  $a_xml_writer->xmlEndTag("ContentObject");
1437  $a_xml_writer->xmlDumpFile($a_target_dir . '/index.xml', false);
1438 
1439  if ($ver == "2004 4th") {
1440  $revision = "4th";
1441  $ver = "2004";
1442  }
1443 
1444  if ($ver == "2004 3rd") {
1445  $revision = "3rd";
1446  $ver = "2004";
1447  }
1448 
1449  // add content css (note: this is also done per item)
1450  $css_dir = $a_target_dir . "/ilias_css_4_2";
1451  ilUtil::makeDir($css_dir);
1452  include_once("./Modules/Scorm2004/classes/class.ilScormExportUtil.php");
1453  ilScormExportUtil::exportContentCSS($this, $css_dir);
1454 
1455  // add manifest
1456  include_once("./Modules/Scorm2004/classes/class.ilContObjectManifestBuilder.php");
1457  $manifestBuilder = new ilContObjectManifestBuilder($this);
1458  $manifestBuilder->buildManifest($ver, $revision);
1459  $manifestBuilder->dump($a_target_dir);
1460 
1461  $xsl = file_get_contents("./Modules/Scorm2004/templates/xsl/module.xsl");
1462  $args = array( '/_xml' => file_get_contents($a_target_dir . "/imsmanifest.xml"), '/_xsl' => $xsl );
1463  $xh = xslt_create();
1464  $output = xslt_process($xh, "arg:/_xml", "arg:/_xsl", null, $args, null);
1465  xslt_free($xh);
1466  fputs(fopen($a_target_dir . '/index.html', 'w+'), $output);
1467  // copy xsd files to target
1468  switch ($ver) {
1469  case "2004":
1470  if ($revision == "3rd") {
1471  ilUtil::rCopy('./libs/ilias/Scorm2004/xsd/adlcp_130_export_2004', $a_target_dir, false);
1472  }
1473 
1474  if ($revision == "4th") {
1475  ilUtil::rCopy('./libs/ilias/Scorm2004/xsd/adlcp_130_export_2004_4th', $a_target_dir, false);
1476  }
1477  break;
1478  case "12":
1479  ilUtil::rCopy('./libs/ilias/Scorm2004/xsd/adlcp_120_export_12', $a_target_dir, false);
1480  break;
1481  }
1482 
1483  $a_xml_writer->_XmlWriter;
1484  }
1485 
1486 
1487  public function exportHTML4PDF($a_inst, $a_target_dir, &$expLog)
1488  {
1489  $tree = new ilTree($this->getId());
1490  $tree->setTableNames('sahs_sc13_tree', 'sahs_sc13_tree_node');
1491  $tree->setTreeTablePK("slm_id");
1492  foreach ($tree->getSubTree($tree->getNodeData($tree->getRootId()), true, 'sco') as $sco) {
1493  include_once("./Modules/Scorm2004/classes/class.ilSCORM2004Sco.php");
1494  $sco_folder = $a_target_dir . "/" . $sco['obj_id'];
1495  ilUtil::makeDir($sco_folder);
1496  $node = new ilSCORM2004Sco($this, $sco['obj_id']);
1497  $node->exportHTML4PDF($a_inst, $sco_folder, $expLog);
1498  }
1499  }
1500 
1501  public function exportPDF($a_inst, $a_target_dir, &$expLog)
1502  {
1503  $a_xml_writer = new ilXmlWriter;
1504  $a_xml_writer->xmlStartTag("ContentObject", array("Type" => "SCORM2004SCO"));
1505  $this->exportXMLMetaData($a_xml_writer);
1506  $tree = new ilTree($this->getId());
1507  $tree->setTableNames('sahs_sc13_tree', 'sahs_sc13_tree_node');
1508  $tree->setTreeTablePK("slm_id");
1509  foreach ($tree->getSubTree($tree->getNodeData($tree->getRootId()), true, 'sco') as $sco) {
1510  include_once("./Modules/Scorm2004/classes/class.ilSCORM2004Sco.php");
1511  $sco_folder = $a_target_dir . "/" . $sco['obj_id'];
1512  ilUtil::makeDir($sco_folder);
1513  $node = new ilSCORM2004Sco($this, $sco['obj_id']);
1514  $node->exportPDFPrepareXmlNFiles($a_inst, $a_target_dir, $expLog, $a_xml_writer);
1515  }
1516  if ($this->getAssignedGlossary() != 0) {
1517  ilUtil::makeDir($a_target_dir . "/glossary");
1518  include_once("./Modules/Glossary/classes/class.ilObjGlossary.php");
1519  include_once("./Modules/Glossary/classes/class.ilGlossaryExport.php");
1520  $glos = new ilObjGlossary($this->getAssignedGlossary(), false);
1521  $glos_export = new ilGlossaryExport($glos, "xml");
1522  $glos->exportXML($a_xml_writer, $glos_export->getInstId(), $a_target_dir . "/glossary", $expLog);
1523  }
1524  $a_xml_writer->xmlEndTag("ContentObject");
1525  include_once 'Services/Transformation/classes/class.ilXML2FO.php';
1526  $xml2FO = new ilXML2FO();
1527  $xml2FO->setXSLTLocation('./Modules/Scorm2004/templates/xsl/contentobject2fo.xsl');
1528  $xml2FO->setXMLString($a_xml_writer->xmlDumpMem());
1529  $xml2FO->setXSLTParams(array('target_dir' => $a_target_dir));
1530  $xml2FO->transform();
1531  $fo_string = $xml2FO->getFOString();
1532  $fo_xml = simplexml_load_string($fo_string);
1533  $fo_ext = $fo_xml->xpath("//fo:declarations");
1534  $fo_ext = $fo_ext[0];
1535  $results = array();
1536  include_once "./Services/Utilities/classes/class.ilFileUtils.php";
1537  ilFileUtils::recursive_dirscan($a_target_dir . "/objects", $results);
1538  if (is_array($results["file"])) {
1539  foreach ($results["file"] as $key => $value) {
1540  $e = $fo_ext->addChild("fox:embedded-file", "", "http://xml.apache.org/fop/extensions");
1541  $e->addAttribute("src", $results[path][$key] . $value);
1542  $e->addAttribute("name", $value);
1543  $e->addAttribute("desc", "");
1544  }
1545  }
1546  $fo_string = $fo_xml->asXML();
1547  $a_xml_writer->_XmlWriter;
1548  return $fo_string;
1549  }
1550 
1551  public function exportHTMLOne($a_inst, $a_target_dir, &$expLog)
1552  {
1553  $one_file = fopen($a_target_dir . '/index.html', 'w+');
1554  $this->exportHTML($a_inst, $a_target_dir, $expLog, $one_file);
1555  fclose($one_file);
1556  }
1557 
1561  public function exportHTML($a_inst, $a_target_dir, &$expLog, $a_one_file = "")
1562  {
1563  // $a_xml_writer = new ilXmlWriter;
1564  // set dtd definition
1565  // $a_xml_writer->xmlSetDtdDef("<!DOCTYPE ContentObject SYSTEM \"http://www.ilias.de/download/dtd/ilias_co_3_7.dtd\">");
1566 
1567  // set generated comment
1568  // $a_xml_writer->xmlSetGenCmt("Export of ILIAS Content Module ". $this->getId()." of installation ".$a_inst.".");
1569 
1570  // set xml header
1571  // $a_xml_writer->xmlHeader();
1572 
1573 
1574  // $a_xml_writer->xmlStartTag("ContentObject", array("Type"=>"SCORM2004LearningModule"));
1575 
1576  // $expLog->write(date("[y-m-d H:i:s] ")."Start Export Sco Objects");
1577  $this->exportHTMLScoObjects($a_inst, $a_target_dir, $expLog, $a_one_file);
1578  // $expLog->write(date("[y-m-d H:i:s] ")."Finished Export Sco Objects");
1579 
1580  // $a_xml_writer->xmlEndTag("ContentObject");
1581 
1582 
1583  /*$toc_tpl = new ilTemplate("tpl.main.html", true, true, false);
1584  $style_name = $ilUser->prefs["style"].".css";
1585  $tpl->setCurrentBlock("css_file");
1586  $tpl->setVariable("CSS_FILE", $style_name);
1587  $tpl->parseCurrentBlock();*/
1588 
1589  if ($a_one_file == "") {
1590  include_once("./Modules/Scorm2004/classes/class.ilContObjectManifestBuilder.php");
1591  $manifestBuilder = new ilContObjectManifestBuilder($this);
1592  $manifestBuilder->buildManifest('12');
1593 
1594  include_once("Services/Frameset/classes/class.ilFramesetGUI.php");
1595  $fs_gui = new ilFramesetGUI();
1596  $fs_gui->setFramesetTitle($this->getTitle());
1597  $fs_gui->setMainFrameSource("");
1598  $fs_gui->setSideFrameSource("toc.html");
1599  $fs_gui->setMainFrameName("content");
1600  $fs_gui->setSideFrameName("toc");
1601  $output = $fs_gui->get();
1602  fputs(fopen($a_target_dir . '/index.html', 'w+'), $output);
1603 
1604  $xsl = file_get_contents("./Modules/Scorm2004/templates/xsl/module.xsl");
1605  $xml = simplexml_load_string($manifestBuilder->writer->xmlDumpMem());
1606  $args = array( '/_xml' => $xml->organizations->organization->asXml(), '/_xsl' => $xsl );
1607  $xh = xslt_create();
1608  $output = xslt_process($xh, "arg:/_xml", "arg:/_xsl", null, $args, null);
1609  xslt_free($xh);
1610  fputs(fopen($a_target_dir . '/toc.html', 'w+'), $output);
1611  }
1612  // $a_xml_writer->_XmlWriter;
1613  }
1614 
1621  public function exportXMLMetaData(&$a_xml_writer)
1622  {
1623  include_once("Services/MetaData/classes/class.ilMD2XML.php");
1624  $md2xml = new ilMD2XML($this->getId(), 0, $this->getType());
1625  $md2xml->setExportMode(true);
1626  $md2xml->startExport();
1627  $a_xml_writer->appendXML($md2xml->getXML());
1628  }
1629 
1636  public function exportXMLStructureObjects(&$a_xml_writer, $a_inst, &$expLog)
1637  {
1638  include_once("Services/MetaData/classes/class.ilMD2XML.php");
1639  $tree = new ilTree($this->getId());
1640  $tree->setTableNames('sahs_sc13_tree', 'sahs_sc13_tree_node');
1641  $tree->setTreeTablePK("slm_id");
1642  $a_xml_writer->xmlStartTag("StructureObject");
1643  foreach ($tree->getFilteredSubTree($tree->getRootId(), array('page')) as $obj) {
1644  if ($obj['type'] == '') {
1645  continue;
1646  }
1647 
1648  //$md2xml = new ilMD2XML($obj['obj_id'], 0, $obj['type']);
1649  $md2xml = new ilMD2XML($this->getId(), $obj['obj_id'], $obj['type']);
1650  $md2xml->setExportMode(true);
1651  $md2xml->startExport();
1652  $a_xml_writer->appendXML($md2xml->getXML());
1653  }
1654  $a_xml_writer->xmlEndTag("StructureObject");
1655  }
1656 
1657 
1664  public function exportXMLScoObjects($a_inst, $a_target_dir, $ver, &$expLog)
1665  {
1666  $tree = new ilTree($this->getId());
1667  $tree->setTableNames('sahs_sc13_tree', 'sahs_sc13_tree_node');
1668  $tree->setTreeTablePK("slm_id");
1669  foreach ($tree->getSubTree($tree->getNodeData($tree->getRootId()), true, array('sco','ass')) as $sco) {
1670  if ($sco['type'] == "sco") {
1671  include_once("./Modules/Scorm2004/classes/class.ilSCORM2004Sco.php");
1672  $sco_folder = $a_target_dir . "/" . $sco['obj_id'];
1673  ilUtil::makeDir($sco_folder);
1674  $node = new ilSCORM2004Sco($this, $sco['obj_id']);
1675  $node->exportScorm($a_inst, $sco_folder, $ver, $expLog);
1676  }
1677  if ($sco['type'] == "ass") {
1678  include_once("./Modules/Scorm2004/classes/class.ilSCORM2004Asset.php");
1679  $sco_folder = $a_target_dir . "/" . $sco['obj_id'];
1680  ilUtil::makeDir($sco_folder);
1681  $node = new ilSCORM2004Asset($this, $sco['obj_id']);
1682  $node->exportScorm($a_inst, $sco_folder, $ver, $expLog);
1683  }
1684  }
1685  }
1686 
1687  /* export page objects to xml (see ilias_co.dtd)
1688  *
1689  * @param object $a_xml_writer ilXmlWriter object that receives the
1690  * xml data
1691  */
1692  public function exportHTMLScoObjects($a_inst, $a_target_dir, &$expLog, $a_one_file = "")
1693  {
1694  $tree = new ilTree($this->getId());
1695  $tree->setTableNames('sahs_sc13_tree', 'sahs_sc13_tree_node');
1696  $tree->setTreeTablePK("slm_id");
1697 
1698  // copy all necessary files now
1699  if ($a_one_file != "") {
1700  $this->prepareHTMLExporter($a_target_dir);
1701 
1702  // put header into file
1703  $sco_tpl = new ilTemplate("tpl.sco.html", true, true, "Modules/Scorm2004");
1704  include_once("./Services/COPage/classes/class.ilCOPageHTMLExport.php");
1705  $page_html_export = new ilCOPageHTMLExport($a_target_dir);
1706  $sco_tpl = $page_html_export->getPreparedMainTemplate($sco_tpl);
1707 
1708  $sco_tpl->setCurrentBlock("js_file");
1709  $sco_tpl->setVariable("JS_FILE", "./js/pure.js");
1710  $sco_tpl->parseCurrentBlock();
1711  $sco_tpl->setCurrentBlock("js_file");
1712  $sco_tpl->setVariable("JS_FILE", "./js/question_handling.js");
1713  $sco_tpl->parseCurrentBlock();
1714 
1715 
1716  $sco_tpl->setCurrentBlock("head");
1717  $sco_tpl->parseCurrentBlock();
1718  fputs($a_one_file, $sco_tpl->get("head"));
1719 
1720  // toc
1721  include_once("./Modules/Scorm2004/classes/class.ilContObjectManifestBuilder.php");
1722  $manifestBuilder = new ilContObjectManifestBuilder($this);
1723  $manifestBuilder->buildManifest('12');
1724  $xsl = file_get_contents("./Modules/Scorm2004/templates/xsl/module.xsl");
1725  $xml = simplexml_load_string($manifestBuilder->writer->xmlDumpMem());
1726  $args = array( '/_xml' => $xml->organizations->organization->asXml(), '/_xsl' => $xsl );
1727  $xh = xslt_create();
1728  $params = array("one_page" => "y");
1729  $output = xslt_process($xh, "arg:/_xml", "arg:/_xsl", null, $args, $params);
1730  xslt_free($xh);
1731  fputs($a_one_file, $output);
1732  }
1733 
1734  foreach ($tree->getSubTree($tree->getNodeData($tree->getRootId()), true, 'sco') as $sco) {
1735  include_once("./Modules/Scorm2004/classes/class.ilSCORM2004Sco.php");
1736  $sco_folder = $a_target_dir . "/" . $sco['obj_id'];
1737  ilUtil::makeDir($sco_folder);
1738  $node = new ilSCORM2004Sco($this, $sco['obj_id']);
1739 
1740  if ($a_one_file == "") {
1741  $node->exportHTML($a_inst, $sco_folder, $expLog, $a_one_file);
1742  } else {
1743  $node->exportHTMLPageObjects(
1744  $a_inst,
1745  $a_target_dir,
1746  $expLog,
1747  'full',
1748  "sco",
1749  $a_one_file,
1750  $sco_tpl
1751  );
1752  }
1753  if ($this->getAssignedGlossary() != 0) {
1754  include_once("./Modules/Glossary/classes/class.ilObjGlossary.php");
1755  $glos = new ilObjGlossary($this->getAssignedGlossary(), false);
1756  //$glos->exportHTML($sco_folder."/glossary", $expLog);
1757  }
1758  }
1759 
1760  // copy all necessary files now
1761  if ($a_one_file != "") {
1762  // put tail into file
1763  fputs($a_one_file, $sco_tpl->get("tail"));
1764  }
1765  }
1766 
1773  public function prepareHTMLExporter($a_target_dir)
1774  {
1775  // system style html exporter
1776  include_once("./Services/Style/System/classes/class.ilSystemStyleHTMLExport.php");
1777  $this->sys_style_html_export = new ilSystemStyleHTMLExport($a_target_dir);
1778  $this->sys_style_html_export->export();
1779 
1780  // init co page html exporter
1781  include_once("./Services/COPage/classes/class.ilCOPageHTMLExport.php");
1782  $this->co_page_html_export = new ilCOPageHTMLExport($a_target_dir);
1783  include_once("./Services/Style/Content/classes/class.ilObjStyleSheet.php");
1784  $this->co_page_html_export->setContentStyleId(
1786  );
1787  $this->co_page_html_export->createDirectories();
1788  $this->co_page_html_export->exportStyles();
1789  $this->co_page_html_export->exportSupportScripts();
1790 
1791  include_once("./Services/MediaObjects/classes/class.ilPlayerUtil.php");
1792  $this->flv_dir = $a_target_dir . "/" . ilPlayerUtil::getFlashVideoPlayerDirectory();
1793 
1794  ilUtil::makeDir($a_target_dir . '/css/yahoo');
1795  ilUtil::makeDir($a_target_dir . '/objects');
1796  ilUtil::makeDir($a_target_dir . '/players');
1797  ilUtil::makeDir($this->flv_dir);
1798 
1799  include_once("./Services/MediaObjects/classes/class.ilPlayerUtil.php");
1800  // copy(ilPlayerUtil::getFlashVideoPlayerFilename(true),
1801  // $a_target_dir.'/js/'.ilPlayerUtil::getFlashVideoPlayerFilename());
1803 
1804  copy('./Modules/Scorm2004/scripts/scorm_2004.js', $a_target_dir . '/js/scorm.js');
1805  copy('./Modules/Scorm2004/scripts/pager.js', $a_target_dir . '/js/pager.js');
1806  copy('./Modules/Scorm2004/scripts/questions/pure.js', $a_target_dir . '/js/pure.js');
1807  copy(
1808  './Modules/Scorm2004/scripts/questions/question_handling.js',
1809  $a_target_dir . '/js/question_handling.js'
1810  );
1811  }
1812 
1820  public function getPublicExportFile($a_type)
1821  {
1822  return $this->public_export_file[$a_type];
1823  }
1824 
1829  public function exportFileItems($a_target_dir, &$expLog)
1830  {
1831  include_once("./Modules/File/classes/class.ilObjFile.php");
1832 
1833  foreach ($this->file_ids as $file_id) {
1834  $expLog->write(date("[y-m-d H:i:s] ") . "File Item " . $file_id);
1835  $file_obj = new ilObjFile($file_id, false);
1836  $file_obj->export($a_target_dir);
1837  unset($file_obj);
1838  }
1839  }
1840 
1844  public function setPublicExportFile($a_type, $a_file)
1845  {
1846  $this->public_export_file[$a_type] = $a_file;
1847  }
1848 
1859  public static function _getMaxScoreForUser($a_id, $a_user)
1860  {
1861  global $DIC;
1862 
1863  $ilDB = $DIC->database();
1864 
1865  $scos = array();
1866 
1867  $result = $ilDB->query(
1868  'SELECT cp_node.cp_node_id '
1869  . 'FROM cp_node, cp_resource, cp_item '
1870  . 'WHERE cp_item.cp_node_id = cp_node.cp_node_id '
1871  . 'AND cp_item.resourceId = cp_resource.id '
1872  . 'AND scormType = ' . $ilDB->quote('sco', 'text') . ' '
1873  . 'AND nodeName = ' . $ilDB->quote('item', 'text') . ' '
1874  . 'AND cp_node.slm_id = ' . $ilDB->quote($a_id, 'integer') . ' '
1875  . 'GROUP BY cp_node.cp_node_id'
1876  );
1877 
1878  while ($row = $ilDB->fetchAssoc($result)) {
1879  array_push($scos, $row['cp_node_id']);
1880  }
1881 
1882  $set = 0; //numbers of SCO that set cmi.score.scaled
1883  $max = null;
1884  for ($i = 0; $i < count($scos); $i++) {
1885  $res = $ilDB->queryF(
1886  'SELECT c_max FROM cmi_node WHERE (user_id = %s AND cp_node_id = %s)',
1887  array('integer', 'integer'),
1888  array($a_user, $scos[$i])
1889  );
1890 
1891  if ($ilDB->numRows($res) > 0) {
1892  $row = $ilDB->fetchAssoc($res);
1893  if ($row['c_max'] != null) {
1894  $set++;
1895  $max = $row['c_max'];
1896  }
1897  }
1898  }
1899  $retVal = ($set == 1) ? $max : null;
1900 
1901  return $retVal;
1902  }
1903 
1904  public static function _getScores2004ForUser($a_cp_node_id, $a_user)
1905  {
1906  global $DIC;
1907 
1908  $ilDB = $DIC->database();
1909  $retAr = array("raw" => null, "max" => null, "scaled" => null);
1910  $val_set = $ilDB->queryF(
1911  "SELECT c_raw, c_max, scaled FROM cmi_node WHERE (user_id = %s AND cp_node_id = %s)",
1912  array('integer', 'integer'),
1913  array($a_user, $a_cp_node_id)
1914  );
1915  if ($val_set->numRows() > 0) {
1916  $val_rec = $ilDB->fetchAssoc($val_set);
1917  $retAr["raw"] = $val_rec['c_raw'];
1918  $retAr["max"] = $val_rec['c_max'];
1919  $retAr["scaled"] = $val_rec['scaled'];
1920  if ($val_rec['scaled'] == null && $val_rec['c_raw'] != null && $val_rec['c_max'] != null) {
1921  $retAr["scaled"] = ($val_rec['c_raw'] / $val_rec['c_max']);
1922  }
1923  }
1924  return $retAr;
1925  }
1926 
1933  public function copyAuthoredContent($a_new_obj)
1934  {
1935  // set/copy stylesheet
1936  include_once("./Services/Style/Content/classes/class.ilObjStyleSheet.php");
1937  $style_id = $this->getStyleSheetId();
1938  if ($style_id > 0 && !ilObjStyleSheet::_lookupStandard($style_id)) {
1939  $style_obj = ilObjectFactory::getInstanceByObjId($style_id);
1940  $new_id = $style_obj->ilClone();
1941  $a_new_obj->setStyleSheetId($new_id);
1942  $a_new_obj->update();
1943  }
1944 
1945  $a_new_obj->createScorm2004Tree();
1946  $source_tree = $this->getTree();
1947  $target_tree_root_id = $a_new_obj->getTree()->readRootId();
1948  $childs = $source_tree->getChilds($source_tree->readRootId());
1949  $a_copied_nodes = array();
1950  include_once("./Modules/Scorm2004/classes/class.ilSCORM2004Node.php");
1951  foreach ($childs as $c) {
1953  $a_new_obj,
1954  $c["child"],
1955  $target_tree_root_id,
1956  IL_LAST_NODE,
1957  "",
1958  $a_copied_nodes,
1959  true,
1960  false
1961  );
1962  }
1963  }
1964 }
const LP_STATUS_COMPLETED_NUM
xslt_create()
static _lookupLastAccess($a_obj_id, $a_usr_id)
Return the last access timestamp for a given user.
getStyleSheetId()
get ID of assigned style sheet object
static _getTrackingItems($a_obj_id)
get all tracking items of scorm object
copyAuthoredContent($a_new_obj)
Copy authored content (everything done with the editor.
xmlStartTag($tag, $attrs=null, $empty=false, $encode=true, $escape=true)
Writes a starttag.
Class ilSCORM2004Sco.
exportHTML4PDF($a_inst, $a_target_dir, &$expLog)
exportHTMLScoObjects($a_inst, $a_target_dir, &$expLog, $a_one_file="")
const IL_CAL_DATETIME
$result
xmlSetDtdDef($dtdDef)
Sets dtd definition.
static rCopy($a_sdir, $a_tdir, $preserveTimeAttributes=false)
Copies content of a directory $a_sdir recursively to a directory $a_tdir.
global $DIC
Definition: saml.php:7
HTML export class for pages.
static exportContentCSS($a_slm_object, $a_target_dir)
Export lm content css to a directory.
Class ilObjGlossary.
xslt_free(&$proc)
const LP_STATUS_NOT_ATTEMPTED
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
static removeCMIDataForUserAndPackage($user_id, $packageId)
HTML export class for system styles.
const LP_STATUS_IN_PROGRESS_NUM
XML writer class.
$target_id
Definition: goto.php:49
getAssignedGlossary()
get assigned glossary
SCORM 2004 Editing tree.
static _refreshStatus($a_obj_id, $a_users=null)
Set dirty.
prepareHTMLExporter($a_target_dir)
Prepare HTML exporter.
static now()
Return current timestamp in Y-m-d H:i:s format.
static _getScores2004ForUser($a_cp_node_id, $a_user)
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false, $include_seconds=false)
Format a date public.
exportXMLStructureObjects(&$a_xml_writer, $a_inst, &$expLog)
export structure objects to xml (see ilias_co.dtd)
user()
Definition: user.php:4
if($source===NULL) $organizations
$ilErr
Definition: raiseError.php:18
const LP_STATUS_IN_PROGRESS
static _lookupStandard($a_id)
Lookup standard flag.
$start
Definition: bench.php:8
setImportSequencing($a_val)
Set import sequencing.
$time
Definition: cron.php:21
$a_type
Definition: workflow.php:92
getDataDirectory($mode="filesystem")
get data directory of lm
exportHTMLOne($a_inst, $a_target_dir, &$expLog)
$r
Definition: example_031.php:79
const LP_STATUS_FAILED
exportFileItems($a_target_dir, &$expLog)
export files of file itmes
static secondsToString($seconds, $force_with_seconds=false, $a_lng=null)
converts seconds to string: Long: 7 days 4 hour(s) ...
foreach($_POST as $key=> $value) $res
getId()
get object id public
static getInstance($a_slm_object, $a_id=0, $a_halt=true)
validate($directory)
Validate all XML-Files in a SCOM-Directory.
deleteTrackingDataOfUsers($a_users)
get all tracked items of current user
getTrackedItems()
get all tracked items of current user
exportXMLMetaData(&$a_xml_writer)
export content objects meta data to xml (see ilias_co.dtd)
const IL_FIRST_NODE
Definition: class.ilTree.php:5
special template class to simplify handling of ITX/PEAR
static getEffectiveContentStyleId($a_style_id, $a_type="")
Get effective Style Id.
executeDragDrop($source_id, $target_id, $first_child, $as_subitem=false, $movecopy="move")
Execute Drag Drop Action.
static _getUniqueScaledScoreForUser($a_id, $a_user)
Get the Unique Scaled Score of a course Conditions: Only one SCO may set cmi.score.scaled.
getTitle()
get object title public
static getFlashVideoPlayerDirectory()
Get flash video player directory.
Date and time handling
$ilUser
Definition: imgupload.php:18
$n
Definition: RandomTest.php:85
Class ilSCORM2004Sequencing.
getType()
get object type public
static getInstanceByObjId($a_obj_id, $stop_on_error=true)
get an instance of an Ilias object by object id
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
importSuccessForSahsUser($user_id, $last_access, $status, $attempts=null, $percentage_completed=null, $sco_total_time_sec=null)
$users
Definition: authpage.php:44
$default
Definition: build.php:20
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
$row
__construct($a_id=0, $a_call_by_reference=true)
Constructor public.
const LP_STATUS_NOT_ATTEMPTED_NUM
const IL_LAST_NODE
Definition: class.ilTree.php:4
exportXMLScoObjects($a_inst, $a_target_dir, $ver, &$expLog)
export page objects to xml (see ilias_co.dtd)
getAttemptsForUser($a_user_id)
get number of atttempts for a certain user and package
exportHTML($a_inst, $a_target_dir, &$expLog, $a_one_file="")
Export SCORM package to HTML.
static _deleteReadEventsForUsers($a_obj_id, array $a_user_ids)
$results
Definition: svg-scanner.php:47
Class ilObjSCORM2004LearningModule.
static copyPlayerFilesToTargetDirectory($a_target_dir)
Copy css files to target dir.
global $ilDB
static pasteTree( $a_target_slm, $a_item_id, $a_parent_id, $a_target, $a_insert_time, &$a_copied_nodes, $a_as_copy=false, $a_from_clipboard=true, $a_source_parent_type="")
Paste item (tree) from clipboard or other learning module to target scorm learning module...
Class ilSCORM2004Asset.
$ret
Definition: parser.php:6
createScorm2004Tree()
Create Scorm 2004 Tree used by Editor.
$i
Definition: disco.tpl.php:19
exportPDF($a_inst, $a_target_dir, &$expLog)
static _getMaxScoreForUser($a_id, $a_user)
Returns score.max for the learning module, refered to the last sco where score.max is set...
static _ISODurationToCentisec($str)
convert ISO 8601 Timeperiods to centiseconds ta
static recursive_dirscan($dir, &$arr)
Recursively scans a given directory and writes path and filename into referenced array.
Export class for content objects.
getPublicExportFile($a_type)
get public export file
static yn2tf($a_yn)
convert "y"/"n" to true/false
static getInstance($a_obj_id)
$key
Definition: croninfo.php:18
Class ilObjSCORMLearningModule.
$_POST["username"]
static _getCourseCompletionForUser($a_id, $a_user)
Get the completion of a SCORM module for a given user.
Scorm 2004 Content Object Manifest export class.
exportScorm($a_inst, $a_target_dir, $ver, &$expLog)
Export (authoring) scorm package.
const LP_STATUS_FAILED_NUM
Class ilFramesetGUI.
$data
Definition: bench.php:6
getModuleVersionForUser($a_user_id)
get module version that tracking data for a user was recorded on