ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilScormAiccDataSet.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2016 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
5 
6 include_once("./Services/DataSet/classes/class.ilDataSet.php");
7 
9 {
10 
14  private $dic;
15 
19  private $db_table = "sahs_lm";
20 
24  public $data = [];
25 
29  private $_archive = [];
30 
34  private $element_db_mapping = [];
35 
39  public $properties = [
40  //"OfflineZipCreated" => "datetime",
41  "Id" => ["db_col" => "id", "db_type" => "integer"],
42  //"EntryPage" => "integer",
43  "APIAdapterName" => ["db_col" => "api_adapter", "db_type" => "text"],
44  "APIFunctionsPrefix" => ["db_col" => "api_func_prefix", "db_type" => "text"],
45  "AssignedGlossary" => ["db_col" => "glossary", "db_type" => "integer"],
46  "AutoContinue" => ["db_col" => "auto_continue", "db_type" => "text"],
47  "AutoReviewChar" => ["db_col" => "auto_review", "db_type" => "text"],
48  "AutoSuspend" => ["db_col" => "auto_suspend", "db_type" => "text"],
49  "Auto_last_visited" => ["db_col" => "auto_last_visited", "db_type" => "text"],
50  "Check_values" => ["db_col" => "check_values", "db_type" => "text"],
51  "Comments" => ["db_col" => "comments", "db_type" => "text"],
52  "CreditMode" => ["db_col" => "credit", "db_type" => "text"],
53  "Debug" => ["db_col" => "debug", "db_type" => "text"],
54  "DebugPw" => ["db_col" => "debugpw", "db_type" => "text"],
55  "DefaultLessonMode" => ["db_col" => "default_lesson_mode", "db_type" => "text"],
56  "Editable" => ["db_col" => "editable", "db_type" => "integer"],
57  "Fourth_edition" => ["db_col" => "fourth_edition", "db_type" => "text"],
58  "Height" => ["db_col" => "height", "db_type" => "integer"],
59  "HideNavig" => ["db_col" => "hide_navig", "db_type" => "text"],
60  "Ie_force_render" => ["db_col" => "ie_force_render", "db_type" => "text"],
61  "Interactions" => ["db_col" => "interactions", "db_type" => "text"],
62  "Localization" => ["db_col" => "localization", "db_type" => "text"],
63  "MasteryScore" => ["db_col" => "mastery_score", "db_type" => "integer"],
64  "MaxAttempt" => ["db_col" => "max_attempt", "db_type" => "integer"],
65  "ModuleVersion" => ["db_col" => "module_version", "db_type" => "integer"],
66  "NoMenu" => ["db_col" => "no_menu", "db_type" => "text"],
67  "Objectives" => ["db_col" => "objectives", "db_type" => "text"],
68  "OfflineMode" => ["db_col" => "offline_mode", "db_type" => "text"],
69  "OpenMode" => ["db_col" => "open_mode", "db_type" => "integer"],
70  "Sequencing" => ["db_col" => "sequencing", "db_type" => "text"],
71  "SequencingExpertMode" => ["db_col" => "seq_exp_mode", "db_type" => "integer"],
72  "Session" => ["db_col" => "unlimited_session", "db_type" => "text"],
73  "StyleSheetId" => ["db_col" => "stylesheet", "db_type" => "integer"],
74  "SubType" => ["db_col" => "c_type", "db_type" => "text"],
75  "Time_from_lms" => ["db_col" => "time_from_lms", "db_type" => "text"],
76  "Tries" => ["db_col" => "question_tries", "db_type" => "integer"],
77  "Width" => ["db_col" => "width", "db_type" => "integer"],
78  "IdSetting" => ["db_col" => "id_setting", "db_type" => "integer"],
79  "NameSetting" => ["db_col" => "name_setting", "db_type" => "integer"]
80  ];
81 
82  public function __construct()
83  {
84  global $DIC;
85  $this->dic = $DIC;
87 
88  foreach ($this->properties as $key => $value) {
89  $this->element_db_mapping[$value["db_col"]] = $key;
90  }
91  }
92 
98  public function readData($a_entity, $a_version, $a_id, $a_field = "")
99  {
100  global $DIC;
101  $ilDB = $DIC['ilDB'];
102 
103  $obj_id = $a_id;
104  $columns = [];
105  foreach ($this->properties as $property) {
106  array_push($columns, $property["db_col"]);
107  }
108 
109  $query = "SELECT " . implode(",", $columns) . " FROM " . $this->db_table;
110  $query .= " WHERE id=" . $ilDB->quote($obj_id, "integer");
111  $result = $ilDB->query($query);
112  $this->data = [];
113  if ($dataset = $ilDB->fetchAssoc($result)) {
114  $this->data = $dataset;
115  }
116 
117  $query = "SELECT title,description FROM object_data";
118  $query .= " WHERE obj_id=" . $ilDB->quote($obj_id, "integer");
119  $result = $ilDB->query($query);
120  while ($dataset = $ilDB->fetchAssoc($result)) {
121  $this->data ["title"] = $dataset["title"];
122  $this->data ["description"] = $dataset["description"];
123  }
124  }
125 
132  public function writeData($a_entity, $a_version, $a_id, $data = [])
133  {
134  global $DIC;
135  $ilDB = $DIC['ilDB'];
136  $ilLog = $DIC['ilLog'];
137  if (count($data) > 0) {
138  $columns = [];
139  foreach ($this->properties as $key => $value) {
140  if ($key == "Id" || $key == "title" || $key == "description") {
141  continue;
142  }
143  //fix localization and mastery_score
144  if ($key == "MasteryScore" && $data[$key][0] == 0) {
145  continue;
146  }
147  if ($key == "Localization" && $data[$key][0] == "") {
148  continue;
149  }
150  //end fix
151  if (isset($data[$key])) {
152  $columns [$value["db_col"]] = [$value["db_type"], $data[$key]];
153  }
154  }
155  if (count($columns) > 0) {
156  $conditions ["id"] = ["integer", $a_id];
157  $ilDB->update($this->db_table, $columns, $conditions);
158  }
159 
160  //setting title and description in table object_data
161  $od_table = "object_data";
162  $od_properties = [
163  "Title" => ["db_col" => "title", "db_type" => "text"],
164  "Description" => ["db_col" => "description", "db_type" => "text"]
165  ];
166  foreach ($od_properties as $key => $value) {
167  if (isset($data[$key])) {
168  $od_columns [$value["db_col"]] = [$value["db_type"], $data[$key]];
169  }
170 
171  if (isset($od_columns) && count($od_columns) > 0) {
172  $od_conditions ["obj_id"] = ["integer", $a_id];
173  $ilDB->update("object_data", $od_columns, $od_conditions);
174  }
175  }
176  } else {
177  $ilLog->write("no module properties for imported object");
178  }
179  }
180 
181  /* retrieve element name by database column name
182  */
183  public function getElementNameByDbColumn($db_col_name)
184  {
185  if ($db_col_name == "title") {
186  return "Title";
187  }
188  if ($db_col_name == "description") {
189  return "Description";
190  }
191  return $this->element_db_mapping[$db_col_name];
192  }
193 
205  public function getExtendedXmlRepresentation($a_entity, $a_schema_version, int $a_ids, string $a_field = "", bool $a_omit_header = false, bool $a_omit_types = false)
206  {
207  global $DIC;
209  $GLOBALS["ilLog"]->write(json_encode($this->getTypes("sahs", "5.1.0"), JSON_PRETTY_PRINT));
210 
211  $this->dircnt = 1;
212 
213  $this->readData($a_entity, $a_schema_version, $a_ids);
214  $id = $this->data["id"];
215 
216  // requirements
217  require_once(dirname(__DIR__, 3) . "/Services/Export/classes/class.ilExport.php");
218  require_once(dirname(__DIR__, 3) . "/Services/Xml/classes/class.ilXmlWriter.php");
219 
220 
221  // prepare archive skeleton
222  $objTypeAndId = "sahs_" . $id;
223  $this->_archive['directories'] = [
224  "exportDir" => ilExport::_getExportDirectory($id)
225  ,"tempDir" => ilExport::_getExportDirectory($id) . "/temp"
226  ,"archiveDir" => time() . "__" . IL_INST_ID . "__" . $objTypeAndId
227  ,"moduleDir" => $objTypeAndId
228  ];
229 
230  $this->_archive['files'] = [
231  "properties" => "properties.xml",
232  "metadata" => "metadata.xml",
233  "manifest" => 'manifest.xml',
234  'scormFile' => "content.zip"
235  ];
236 
237  // Prepare temp storage on the local filesystem
238  if (!file_exists($this->_archive['directories']['exportDir'])) {
239  mkdir($this->_archive['directories']['exportDir'], 0755, true);
240  //$DIC->filesystem()->storage()->createDir($this->_archive['directories']['tempDir']);
241  }
242  if (!file_exists($this->_archive['directories']['tempDir'])) {
243  mkdir($this->_archive['directories']['tempDir'], 0755, true);
244  }
245 
246  // build metadata xml file
247  file_put_contents(
248  $this->_archive['directories']['tempDir'] . "/" . $this->_archive['files']['metadata'],
249  $this->buildMetaData($id)
250  );
251 
252  // build manifest xml file
253  file_put_contents(
254  $this->_archive['directories']['tempDir'] . "/" . $this->_archive['files']['manifest'],
255  $this->buildManifest()
256  );
257 
258  // build content zip file
259  if (isset($this->_archive['files']['scormFile'])) {
260  $lmDir = ilUtil::getWebspaceDir("filesystem") . "/lm_data/lm_" . $id;
261  ilUtil::zip($lmDir, $this->_archive['directories']['tempDir'] . "/" . substr($this->_archive['files']['scormFile'], 0, -4), true);
262  }
263 
264  // build property xml file
265  file_put_contents(
266  $this->_archive['directories']['tempDir'] . "/" . $this->_archive['files']['properties'],
267  $this->buildProperties($a_entity, $a_omit_header)
268  );
269 
270  // zip tempDir and append to export folder
271  $fileName = $this->_archive['directories']['exportDir'] . "/" . $this->_archive['directories']['archiveDir'] . ".zip";
272  $zArchive = new ZipArchive();
273  if ($zArchive->open($fileName, ZipArchive::CREATE) !== true) {
274  exit("cannot open <$fileName>\n");
275  }
276  $zArchive->addFile(
277  $this->_archive['directories']['tempDir'] . "/" . $this->_archive['files']['properties'],
278  $this->_archive['directories']['archiveDir'] . '/properties.xml'
279  );
280  $zArchive->addFile(
281  $this->_archive['directories']['tempDir'] . "/" . $this->_archive['files']['manifest'],
282  $this->_archive['directories']['archiveDir'] . '/' . "manifest.xml"
283  );
284  $zArchive->addFile(
285  $this->_archive['directories']['tempDir'] . "/" . $this->_archive['files']['metadata'],
286  $this->_archive['directories']['archiveDir'] . '/' . "metadata.xml"
287  );
288  if (isset($this->_archive['files']['scormFile'])) {
289  $zArchive->addFile(
290  $this->_archive['directories']['tempDir'] . "/" . $this->_archive['files']['scormFile'],
291  $this->_archive['directories']['archiveDir'] . '/content.zip'
292  );
293  }
294  $zArchive->close();
295 
296  // unlink tempDir and its content
297  unlink($this->_archive['directories']['tempDir'] . "/metadata.xml");
298  unlink($this->_archive['directories']['tempDir'] . "/manifest.xml");
299  unlink($this->_archive['directories']['tempDir'] . "/properties.xml");
300  if (isset($this->_archive['files']['scormFile']) && file_exists($this->_archive['directories']['tempDir'] . "/content.zip")) {
301  unlink($this->_archive['directories']['tempDir'] . "/content.zip");
302  }
303 
304  return $fileName;
305  }
306 
307 
308 
309  public function buildMetaData($id)
310  {
311  require_once("Services/MetaData/classes/class.ilMD2XML.php");
312  $md2xml = new ilMD2XML($id, $id, "sahs");
313  $md2xml->startExport();
314  $xml = $md2xml->getXML();
315  return $xml;
316  }
317 
325  protected function getTypes($a_entity, $a_version)
326  {
327  if ($a_entity == "sahs") {
328  switch ($a_version) {
329  case "5.1.0":
330  $types = [];
331  foreach ($this->properties as $key => $value) {
332  $types[$key] = $value["db_type"];
333  }
334  return $types;
335  break;
336  }
337  }
338  }
339 
345  public function getXmlNamespace($a_entity, $a_schema_version)
346  {
347  return "http://www.ilias.de/xml/Modules/ScormAicc/" . $a_entity;
348  }
349 
350  public function getDependencies()
351  {
352  return null;
353  }
354 
355  public function getSupportedVersions()
356  {
357  return ["5.1.0"];
358  }
359 
363  private function buildManifest() : string
364  {
365  $manWriter = new ilXmlWriter();
366  $manWriter->xmlHeader();
367  foreach ($this->_archive['files'] as $key => $value) {
368  $manWriter->xmlElement($key, null, $value, true, true);
369  }
370 
371  return $manWriter->xmlDumpMem(true);
372  }
373 
379  private function buildProperties($a_entity, $a_omit_header = false)
380  {
381  $writer = new ilXmlWriter();
382 
383  if (!$a_omit_header) {
384  $writer->xmlHeader();
385  }
386 
387  $writer->appendXML("\n");
388  $writer->xmlStartTag('DataSet', array(
389  "InstallationId" => IL_INST_ID,
390  "InstallationUrl" => ILIAS_HTTP_PATH,
391  "TopEntity" => $a_entity
392  ));
393 
394  $writer->appendXML("\n");
395 
396  foreach ($this->data as $key => $value) {
397  $writer->xmlElement($this->getElementNameByDbColumn($key), null, $value, true, true);
398  $writer->appendXML("\n");
399  }
400 
401  $writer->xmlEndTag("DataSet");
402 
403  return $writer->xmlDumpMem(false);
404  }
405 }
exit
Definition: login.php:29
readData($a_entity, $a_version, $a_id, $a_field="")
Read data.
const IL_INST_ID
Definition: constants.php:38
$result
XML writer class.
__construct()
Constructor.
global $DIC
Definition: goto.php:24
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
$xml
Definition: metadata.php:332
$query
static zip($a_dir, $a_file, $compress_content=false)
zips given directory/file into given zip.file
buildProperties($a_entity, $a_omit_header=false)
__construct(Container $dic, ilPlugin $plugin)
writeData($a_entity, $a_version, $a_id, $data=[])
Write properties for imported object (actually updates !!)
global $ilDB
getElementNameByDbColumn($db_col_name)
static _getExportDirectory($a_obj_id, $a_type="xml", $a_obj_type="", $a_entity="")
Get export directory for an repository object.
A dataset contains in data in a common structure that can be shared and transformed for different pur...
getXmlNamespace($a_entity, $a_schema_version)
Get xml namespace.
if(! $in) $columns
Definition: Utf8Test.php:45
static getWebspaceDir($mode="filesystem")
get webspace directory
getTypes($a_entity, $a_version)
Get field types for entity.