ILIAS  release_7 Revision v7.30-3-g800a261c036
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
6include_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}
$result
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
if(! $in) $columns
Definition: Utf8Test.php:45
An exception for terminatinating execution or to throw for unit testing.
Customizing of pimple-DIC for ILIAS.
Definition: Container.php:19
A dataset contains in data in a common structure that can be shared and transformed for different pur...
__construct()
Constructor.
static _getExportDirectory($a_obj_id, $a_type="xml", $a_obj_type="", $a_entity="")
Get export directory for an repository object.
getSupportedVersions()
Get supported version.
writeData($a_entity, $a_version, $a_id, $data=[])
Write properties for imported object (actually updates !!)
buildProperties($a_entity, $a_omit_header=false)
readData($a_entity, $a_version, $a_id, $a_field="")
Read data.
getElementNameByDbColumn($db_col_name)
getXmlNamespace($a_entity, $a_schema_version)
Get xml namespace.
getTypes($a_entity, $a_version)
Get field types for entity.
static getWebspaceDir($mode="filesystem")
get webspace directory
static zip($a_dir, $a_file, $compress_content=false)
zips given directory/file into given zip.file
XML writer class.
const IL_INST_ID
Definition: constants.php:38
global $DIC
Definition: goto.php:24
exit
Definition: login.php:29
$xml
Definition: metadata.php:332
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$query
global $ilDB