ILIAS  release_8 Revision v8.24
class.ilAdvancedMDParser.php
Go to the documentation of this file.
1<?php
2
3declare(strict_types=1);
4/******************************************************************************
5 *
6 * This file is part of ILIAS, a powerful learning management system.
7 *
8 * ILIAS is licensed with the GPL-3.0, you should have received a copy
9 * of said license along with the source code.
10 *
11 * If this is not the case or you just want to try ILIAS, you'll find
12 * us at:
13 * https://www.ilias.de
14 * https://github.com/ILIAS-eLearning
15 *
16 *****************************************************************************/
23{
24 protected int $obj_id;
25 protected int $rec_id = 0;
27 protected string $cdata = "";
29
33 protected array $value_records = [];
34
36 protected array $record_ids = [];
37
38 // local adv md record support
39 protected ?array $local_record = null;
40 protected array $local_rec_map = [];
41 protected array $local_rec_fields_map = [];
42
46 protected ilLogger $log;
47
48 public function __construct(string $a_obj_id, ilImportMapping $a_mapping)
49 {
51
52 $this->log = ilLoggerFactory::getLogger('amet');
53
54 $parts = explode(":", $a_obj_id);
55 $this->obj_id = (int) $parts[0];
56 $this->mapping = $a_mapping;
57 }
58
59 public function setHandlers($a_xml_parser): void
60 {
61 $this->sax_controller = new ilSaxController();
62 $this->sax_controller->setHandlers($a_xml_parser);
63 $this->sax_controller->setDefaultElementHandler($this);
64 }
65
66 public function createLocalRecord(int $a_old_id, string $a_xml, int $a_obj_id, ?string $a_sub_type = null): void
67 {
68 $tmp_file = ilFileUtils::ilTempnam();
69 file_put_contents($tmp_file, $a_xml);
70
71 // see ilAdvancedMDSettingsGUI::importRecord()
72 $parser = null;
73 try {
74 // the (old) record parser does only support files
75 $parser = new ilAdvancedMDRecordParser($tmp_file);
76 $parser->setContext($a_obj_id, ilObject::_lookupType($a_obj_id), $a_sub_type);
78 $parser->startParsing();
80 $parser->startParsing();
81 } catch (ilSaxParserException $exc) {
82 $this->log->error('Parsing failed with message: ' . $exc->getMessage());
83 return;
84 } finally {
85 unlink($tmp_file);
86 }
87 $map = $parser->getRecordMap();
88 foreach ($map as $record_id => $fields) {
89 $this->local_rec_fields_map[$record_id] = $fields;
90
91 // needed for glossary field order
92 foreach ($fields as $import_id => $new_id) {
93 $import_ids = explode('_', $import_id);
94 $old_id = array_pop($import_ids);
95 $this->mapping->addMapping("Services/AdvancedMetaData", "lfld", $old_id, (string) $new_id);
96 }
97 }
98 $map_keys = array_keys($map);
99 $new_id = array_shift($map_keys);
100 $this->local_rec_map[$a_old_id] = $new_id;
101 }
102
103 public function handlerBeginTag($a_xml_parser, string $a_name, array $a_attribs): void
104 {
105 switch ($a_name) {
106 case 'AdvancedMetaData':
107 break;
108
109 case 'Record':
110 $this->local_record = array('id' => $a_attribs['local_id']);
111 break;
112
113 case 'Value':
114 $this->initValue(
115 (string) $a_attribs['id'],
116 (string) $a_attribs['sub_type'],
117 (int) $a_attribs['sub_id'],
118 isset($a_attribs['local_rec_id']) ? (int) $a_attribs['local_rec_id'] : null
119 );
120 break;
121 }
122 }
123
124 public function handlerEndTag($a_xml_parser, string $a_name): void
125 {
126 switch ($a_name) {
127 case 'AdvancedMetaData':
128 // we need to write all records that have been created (1 for each sub-item)
129 foreach ($this->value_records as $record) {
130 $record->write();
131 }
132 break;
133
134 case 'Record':
135 $this->local_record['xml'] = base64_decode(trim($this->cdata));
136 $this->log->debug("Local Record XML: " . $this->local_record['xml']);
137 break;
138
139 case 'Value':
140 $value = trim($this->cdata);
141 $this->log->debug("End Tag Value: -" . is_object($this->current_value) . "-" . $value);
142 if (is_object($this->current_value) && $value != "") {
143 $this->current_value->importValueFromXML($value);
144 }
145 break;
146 }
147 $this->cdata = '';
148 }
149
150 public function handlerCharacterData($a_xml_parser, string $a_data): void
151 {
152 if ($a_data != "\n") {
153 // Replace multiple tabs with one space
154 $a_data = preg_replace("/\t+/", " ", $a_data);
155
156 $this->cdata .= $a_data;
157 }
158 }
159
160 protected function initValue(
161 string $a_import_id,
162 string $a_sub_type = "",
163 int $a_sub_id = 0,
164 int $a_local_rec_id = null
165 ): void {
166 $this->current_value = null;
167
168 // get parent objects
169 $new_parent_id = (int) $this->mapping->getMapping("Services/AdvancedMetaData", "parent", (string) $this->obj_id);
170 $this->log->notice('Found new parent id:' . $new_parent_id);
171 if (!$new_parent_id) {
172 return;
173 }
174 $new_sub_id = '';
175 if ($a_sub_type && strcmp($a_sub_type, '-') !== 0) {
176 $new_sub_id = $this->mapping->getMapping(
177 "Services/AdvancedMetaData",
178 "advmd_sub_item",
179 "advmd:" . $a_sub_type . ":" . $a_sub_id
180 );
181 if (!$new_sub_id) {
182 return;
183 }
184 }
185
186 // init local record?
187 // done here because we need object context
188 if (is_array($this->local_record)) {
189 $this->createLocalRecord(
190 (int) $this->local_record['id'],
191 $this->local_record['xml'],
192 $new_parent_id,
193 $a_sub_type
194 );
195 $this->local_record = null;
196 }
197
198 $rec_id = null;
199
200 // find record via import id
201 if (!$a_local_rec_id) {
202 if ($field = ilAdvancedMDFieldDefinition::getInstanceByImportId($a_import_id)) {
203 $rec_id = $field->getRecordId();
204 }
205 } // (new) local record
206 else {
207 $rec_id = $this->local_rec_map[$a_local_rec_id];
208 }
209
210 if (!$rec_id) {
211 return;
212 }
213
214 // init record definitions
215 if ($a_sub_type) {
216 $rec_idx = $rec_id . ";" . $a_sub_type . ";" . $new_sub_id;
217 if (!array_key_exists($rec_idx, $this->value_records)) {
218 $this->value_records[$rec_idx] = new ilAdvancedMDValues(
219 $rec_id,
220 $new_parent_id,
221 $a_sub_type,
222 $new_sub_id
223 );
224 }
225 } else {
226 $rec_idx = $rec_id . ";;";
227 if (!array_key_exists($rec_idx, $this->value_records)) {
228 $this->value_records[$rec_idx] = new ilAdvancedMDValues($rec_id, $new_parent_id);
229 }
230 }
231
232 // init ADTGroup before definitions to bind definitions to group
233 $this->value_records[$rec_idx]->getADTGroup();
234
235 // find element with import id
236 $this->log->debug("Find element: " . $a_import_id . ", local rec_id: " . $a_local_rec_id);
237 if (!$a_local_rec_id) {
238 foreach ($this->value_records[$rec_idx]->getDefinitions() as $def) {
239 if ($a_import_id == $def->getImportId()) {
240 $this->current_value = $def;
241 break;
242 }
243 }
244 } else {
245 // find element in new local record
246 $field_id = $this->local_rec_fields_map[$rec_id][$a_import_id];
247 if ($field_id) {
248 $this->log->debug("- Field id: " . $field_id);
249 foreach ($this->value_records[$rec_idx]->getDefinitions() as $def) {
250 $this->log->debug("- Def field id: " . $def->getFieldId());
251 if ($field_id == $def->getFieldId()) {
252 $this->current_value = $def;
253 break;
254 }
255 }
256 } else {
257 $this->log->debug("- No Field id. local rec: " . $a_local_rec_id .
258 ", rec id:" . $rec_id . ", import id: " . $a_import_id . ", map: " . print_r(
259 $this->local_rec_fields_map,
260 true
261 ));
262 }
263 }
264
265 // record will be selected for parent
266 // see ilAdvancedMetaDataImporter
267 if ($this->current_value &&
268 !$a_local_rec_id) {
269 $this->record_ids[$new_parent_id][$a_sub_type][] = $rec_id;
270 }
271 }
272
276 public function getRecordIds(): array
277 {
278 return $this->record_ids;
279 }
280}
static getInstanceByImportId(string $a_import_id)
setHandlers($a_xml_parser)
Set event handlers.
initValue(string $a_import_id, string $a_sub_type="", int $a_sub_id=0, int $a_local_rec_id=null)
handlerCharacterData($a_xml_parser, string $a_data)
handlerBeginTag($a_xml_parser, string $a_name, array $a_attribs)
createLocalRecord(int $a_old_id, string $a_xml, int $a_obj_id, ?string $a_sub_type=null)
handlerEndTag($a_xml_parser, string $a_name)
ilAdvancedMDFieldDefinition $current_value
__construct(string $a_obj_id, ilImportMapping $a_mapping)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static ilTempnam(?string $a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getLogger(string $a_component_id)
Get component logger.
Component logger with individual log levels by component id.
static _lookupType(int $id, bool $reference=false)
Controller class for sax element handlers.
SaxParserException thrown by ilSaxParser if property throwException is set.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Interface definition for sax subset parsers.
if($clientAssertionType !='urn:ietf:params:oauth:client-assertion-type:jwt-bearer'|| $grantType !='client_credentials') $parts
Definition: ltitoken.php:64
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc