ILIAS  release_8 Revision v8.23
class.ilScormAiccDataSet.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
22 {
23  private string $db_table;
24  public array $properties;
25  private array $_archive;
26  private array $element_db_mapping;
27 
28  public function __construct()
29  {
30  $this->db_table = "sahs_lm";
31  $this->_archive = [];
32  $this->properties = [
33  "Id" => ["db_col" => "id", "db_type" => "integer"],
34  "APIAdapterName" => ["db_col" => "api_adapter", "db_type" => "text"],
35  "APIFunctionsPrefix" => ["db_col" => "api_func_prefix", "db_type" => "text"],
36  "AssignedGlossary" => ["db_col" => "glossary", "db_type" => "integer"],
37  "AutoContinue" => ["db_col" => "auto_continue", "db_type" => "text"],
38  "AutoReviewChar" => ["db_col" => "auto_review", "db_type" => "text"],
39  "AutoSuspend" => ["db_col" => "auto_suspend", "db_type" => "text"],
40  "Auto_last_visited" => ["db_col" => "auto_last_visited", "db_type" => "text"],
41  "Check_values" => ["db_col" => "check_values", "db_type" => "text"],
42  "Comments" => ["db_col" => "comments", "db_type" => "text"],
43  "CreditMode" => ["db_col" => "credit", "db_type" => "text"],
44  "Debug" => ["db_col" => "debug", "db_type" => "text"],
45  "DebugPw" => ["db_col" => "debugpw", "db_type" => "text"],
46  "DefaultLessonMode" => ["db_col" => "default_lesson_mode", "db_type" => "text"],
47  "Editable" => ["db_col" => "editable", "db_type" => "integer"],
48  "Fourth_edition" => ["db_col" => "fourth_edition", "db_type" => "text"],
49  "Height" => ["db_col" => "height", "db_type" => "integer"],
50  "HideNavig" => ["db_col" => "hide_navig", "db_type" => "text"],
51  "Ie_force_render" => ["db_col" => "ie_force_render", "db_type" => "text"],
52  "Interactions" => ["db_col" => "interactions", "db_type" => "text"],
53  "Localization" => ["db_col" => "localization", "db_type" => "text"],
54  "MasteryScore" => ["db_col" => "mastery_score", "db_type" => "integer"],
55  "MaxAttempt" => ["db_col" => "max_attempt", "db_type" => "integer"],
56  "ModuleVersion" => ["db_col" => "module_version", "db_type" => "integer"],
57  "NoMenu" => ["db_col" => "no_menu", "db_type" => "text"],
58  "Objectives" => ["db_col" => "objectives", "db_type" => "text"],
59  "OfflineMode" => ["db_col" => "offline_mode", "db_type" => "text"],
60  "OpenMode" => ["db_col" => "open_mode", "db_type" => "integer"],
61  "Sequencing" => ["db_col" => "sequencing", "db_type" => "text"],
62  "SequencingExpertMode" => ["db_col" => "seq_exp_mode", "db_type" => "integer"],
63  "Session" => ["db_col" => "unlimited_session", "db_type" => "text"],
64  "StyleSheetId" => ["db_col" => "stylesheet", "db_type" => "integer"],
65  "SubType" => ["db_col" => "c_type", "db_type" => "text"],
66  "Time_from_lms" => ["db_col" => "time_from_lms", "db_type" => "text"],
67  "Tries" => ["db_col" => "question_tries", "db_type" => "integer"],
68  "Width" => ["db_col" => "width", "db_type" => "integer"],
69  "IdSetting" => ["db_col" => "id_setting", "db_type" => "integer"],
70  "NameSetting" => ["db_col" => "name_setting", "db_type" => "integer"]
71  ];
72 
73  $this->element_db_mapping = [];
74  foreach ($this->properties as $key => $value) {
75  $this->element_db_mapping [$value["db_col"]] = $key;
76  }
77  }
78 
82  protected function getDependencies(
83  string $a_entity,
84  string $a_version,
85  ?array $a_rec = null,
86  ?array $a_ids = null
87  ): array {
88  return [];
89  }
90 
91  public function writeData(string $a_entity, string $a_version, int $a_id, array $data): void
92  {
93  global $DIC;
94  $ilDB = $DIC->database();
95  $ilLog = ilLoggerFactory::getLogger('sahs');
96  if (count($data) > 0) {
97  $columns = [];
98  foreach ($this->properties as $key => $value) {
99  if ($key === "Id" || $key === "title" || $key === "description") {
100  continue;
101  }
102  //fix localization and mastery_score
103  if ($key === "MasteryScore" && isset($data[$key][0]) && $data[$key][0] == 0) {
104  continue;
105  }
106  if ($key === "Localization" && isset($data[$key][0]) && $data[$key][0] == "") {
107  continue;
108  }
109  //end fix
110  if (isset($data[$key]) && is_array($data[$key])) {
111  if (count($data[$key]) > 0) {
112  $columns [$value["db_col"]] = [$value["db_type"], $data[$key][0]];
113  }
114  }
115  }
116  if (is_array($columns)) {
117  if (count($columns) > 0) {
118  $conditions ["id"] = ["integer", $a_id];
119  $ilDB->update($this->db_table, $columns, $conditions);
120  }
121  }
122 
123  //setting title and description in table object_data
124  $od_table = "object_data";
125  $od_properties = [
126  "Title" => ["db_col" => "title", "db_type" => "text"],
127  "Description" => ["db_col" => "description", "db_type" => "text"]
128  ];
129  foreach ($od_properties as $key => $value) {
130  if (isset($data[$key]) && is_array($data[$key])) {
131  if (count($data[$key]) > 0) {
132  $od_columns [$value["db_col"]] = [$value["db_type"], $data[$key][0]];
133  }
134  }
135 
136  if (isset($od_columns) && is_array($od_columns)) {
137  if (count($od_columns) > 0) {
138  $od_conditions ["obj_id"] = ["integer", $a_id];
139  $ilDB->update("object_data", $od_columns, $od_conditions);
140  }
141  }
142  }
143  } else {
144  $ilLog->write("no module properties for imported object");
145  }
146  }
147 
152  string $a_entity,
153  string $a_schema_version,
154  array $a_ids,
155  string $a_field = "",
156  bool $a_omit_header = false,
157  bool $a_omit_types = false
158  ): string {
159  $GLOBALS['DIC']["ilLog"]->write(json_encode($this->getTypes("sahs", "5.1.0"), JSON_PRETTY_PRINT));
160 
161  $this->dircnt = 1;
162 
163  $this->readData($a_entity, $a_schema_version, $a_ids, $a_field = "");
164  $id = (int) $this->data["id"];
165  $exportDir = ilExport::_getExportDirectory((int) $id, "xml", "sahs");
166 
167  // prepare archive skeleton
168  $objTypeAndId = "sahs_" . $id;
169  $this->_archive['directories'] = [
170  "exportDir" => ilExport::_getExportDirectory($id)
171  ,"tempDir" => ilExport::_getExportDirectory($id) . "/temp"
172  ,"archiveDir" => time() . "__" . IL_INST_ID . "__" . $objTypeAndId
173  ,"moduleDir" => $objTypeAndId
174  ];
175 
176  $this->_archive['files'] = [
177  "properties" => "properties.xml",
178  "metadata" => "metadata.xml",
179  "manifest" => 'manifest.xml',
180  'scormFile' => "content.zip"
181  ];
182 
183  // Prepare temp storage on the local filesystem
184  if (!file_exists($this->_archive['directories']['exportDir'])) {
185  mkdir($this->_archive['directories']['exportDir'], 0755, true);
186  //$DIC->filesystem()->storage()->createDir($this->_archive['directories']['tempDir']);
187  }
188  if (!file_exists($this->_archive['directories']['tempDir'])) {
189  mkdir($this->_archive['directories']['tempDir'], 0755, true);
190  }
191 
192  // build metadata xml file
193  file_put_contents(
194  $this->_archive['directories']['tempDir'] . "/" . $this->_archive['files']['metadata'],
195  $this->buildMetaData($id)
196  );
197 
198  // build manifest xml file
199  file_put_contents(
200  $this->_archive['directories']['tempDir'] . "/" . $this->_archive['files']['manifest'],
201  $this->buildManifest()
202  );
203 
204  // build content zip file
205  if (isset($this->_archive['files']['scormFile'])) {
206  $lmDir = ilFileUtils::getWebspaceDir("filesystem") . "/lm_data/lm_" . $id;
207  ilFileUtils::zip($lmDir, $this->_archive['directories']['tempDir'] . "/" . substr($this->_archive['files']['scormFile'], 0, -4), true);
208  }
209 
210  // build property xml file
211  file_put_contents(
212  $this->_archive['directories']['tempDir'] . "/" . $this->_archive['files']['properties'],
213  $this->buildProperties($a_entity, $a_omit_header)
214  );
215 
216  // zip tempDir and append to export folder
217  $fileName = $this->_archive['directories']['exportDir'] . "/" . $this->_archive['directories']['archiveDir'] . ".zip";
218  $zArchive = new ZipArchive();
219  if ($zArchive->open($fileName, ZipArchive::CREATE) !== true) {
220  exit("cannot open <$fileName>\n");
221  }
222  $zArchive->addFile(
223  $this->_archive['directories']['tempDir'] . "/" . $this->_archive['files']['properties'],
224  $this->_archive['directories']['archiveDir'] . '/properties.xml'
225  );
226  $zArchive->addFile(
227  $this->_archive['directories']['tempDir'] . "/" . $this->_archive['files']['manifest'],
228  $this->_archive['directories']['archiveDir'] . '/' . "manifest.xml"
229  );
230  $zArchive->addFile(
231  $this->_archive['directories']['tempDir'] . "/" . $this->_archive['files']['metadata'],
232  $this->_archive['directories']['archiveDir'] . '/' . "metadata.xml"
233  );
234  if (isset($this->_archive['files']['scormFile'])) {
235  $zArchive->addFile(
236  $this->_archive['directories']['tempDir'] . "/" . $this->_archive['files']['scormFile'],
237  $this->_archive['directories']['archiveDir'] . '/content.zip'
238  );
239  }
240  $zArchive->close();
241 
242  // unlink tempDir and its content
243  unlink($this->_archive['directories']['tempDir'] . "/metadata.xml");
244  unlink($this->_archive['directories']['tempDir'] . "/manifest.xml");
245  unlink($this->_archive['directories']['tempDir'] . "/properties.xml");
246  if (isset($this->_archive['files']['scormFile']) && file_exists($this->_archive['directories']['tempDir'] . "/content.zip")) {
247  unlink($this->_archive['directories']['tempDir'] . "/content.zip");
248  }
249 
250  return $fileName;
251  }
252 
259  protected function getTypes(string $a_entity, string $a_version): array
260  {
261  if ($a_entity === "sahs") {
262  switch ($a_version) {
263  case "5.1.0":
264  $types = [];
265  foreach ($this->properties as $key => $value) {
266  $types[$key] = $value["db_type"];
267  }
268  return $types;
269  }
270  }
271  return [];
272  }
273 
274  public function readData(string $a_entity, string $a_version, array $a_ids, string $a_field = ""): void
275  {
276  global $DIC;
277  $ilDB = $DIC->database();
278 
279  $obj_id = (int) $a_ids[0];
280  $columns = [];
281  foreach ($this->properties as $property) {
282  $columns[] = $property["db_col"];
283  }
284 
285  $query = "SELECT " . implode(",", $columns) . " FROM " . $this->db_table;
286  $query .= " WHERE id=" . $ilDB->quote($obj_id, "integer");
287  $result = $ilDB->query($query);
288  $this->data = [];
289  if ($dataset = $ilDB->fetchAssoc($result)) {
290  $this->data = $dataset;
291  }
292 
293  $query = "SELECT title,description FROM object_data";
294  $query .= " WHERE obj_id=" . $ilDB->quote($obj_id, "integer");
295  $result = $ilDB->query($query);
296  while ($dataset = $ilDB->fetchAssoc($result)) {
297  $this->data ["title"] = $dataset["title"];
298  $this->data ["description"] = $dataset["description"];
299  }
300  }
301 
305  public function getElementNameByDbColumn(string $db_col_name): string
306  {
307  if ($db_col_name === "title") {
308  return "Title";
309  }
310  if ($db_col_name === "description") {
311  return "Description";
312  }
313  return $this->element_db_mapping[$db_col_name];
314  }
315 
316  public function buildMetaData(int $id): string
317  {
318  $md2xml = new ilMD2XML($id, $id, "sahs");
319  $md2xml->startExport();
320  return $md2xml->getXML();
321  }
322 
326  protected function getXmlNamespace(string $a_entity, string $a_schema_version): string
327  {
328  return "http://www.ilias.de/xml/Modules/ScormAicc/" . $a_entity;
329  }
330 
334  public function getSupportedVersions(): array
335  {
336  return ["5.1.0"];
337  }
338 
342  private function buildManifest(): string
343  {
344  $manWriter = new ilXmlWriter();
345  $manWriter->xmlHeader();
346  foreach ($this->_archive['files'] as $key => $value) {
347  $manWriter->xmlElement($key, null, $value, true, true);
348  }
349 
350  return $manWriter->xmlDumpMem(true);
351  }
352 
358  private function buildProperties($a_entity, bool $a_omit_header = false): string
359  {
360  $writer = new ilXmlWriter();
361 
362  if (!$a_omit_header) {
363  $writer->xmlHeader();
364  }
365 
366  $writer->appendXML("\n");
367  $writer->xmlStartTag('DataSet', array(
368  "InstallationId" => IL_INST_ID,
369  "InstallationUrl" => ILIAS_HTTP_PATH,
370  "TopEntity" => $a_entity
371  ));
372 
373  $writer->appendXML("\n");
374 
375  foreach ($this->data as $key => $value) {
376  $writer->xmlElement($this->getElementNameByDbColumn($key), null, $value, true, true);
377  $writer->appendXML("\n");
378  }
379 
380  $writer->xmlEndTag("DataSet");
381 
382  return $writer->xmlDumpMem(false);
383  }
384 
385 }
static getWebspaceDir(string $mode="filesystem")
get webspace directory
getDependencies(string $a_entity, string $a_version, ?array $a_rec=null, ?array $a_ids=null)
exit
Definition: login.php:28
const IL_INST_ID
Definition: constants.php:40
static getLogger(string $a_component_id)
Get component logger.
getTypes(string $a_entity, string $a_version)
Get field types for entity.
getXmlNamespace(string $a_entity, string $a_schema_version)
Get xml namespace.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getExportDirectory(int $a_obj_id, string $a_type="xml", string $a_obj_type="", string $a_entity="")
Get export directory for an repository object.
getExtendedXmlRepresentation(string $a_entity, string $a_schema_version, array $a_ids, string $a_field="", bool $a_omit_header=false, bool $a_omit_types=false)
own getXmlRepresentation function to embed zipfile in xml
global $DIC
Definition: feed.php:28
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
writeData(string $a_entity, string $a_version, int $a_id, array $data)
string $key
Consumer key/client ID value.
Definition: System.php:193
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$query
buildProperties($a_entity, bool $a_omit_header=false)
static zip(string $a_dir, string $a_file, bool $compress_content=false)
zips given directory/file into given zip.file
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
readData(string $a_entity, string $a_version, array $a_ids, string $a_field="")
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getElementNameByDbColumn(string $db_col_name)
retrieve element name by database column name