ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilAdvancedMDRecordParser.php
Go to the documentation of this file.
1<?php
2/*
3 +-----------------------------------------------------------------------------+
4 | ILIAS open source |
5 +-----------------------------------------------------------------------------+
6 | Copyright (c) 1998-2006 ILIAS open source, University of Cologne |
7 | |
8 | This program is free software; you can redistribute it and/or |
9 | modify it under the terms of the GNU General Public License |
10 | as published by the Free Software Foundation; either version 2 |
11 | of the License, or (at your option) any later version. |
12 | |
13 | This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21 +-----------------------------------------------------------------------------+
22*/
23
34include_once('Services/AdvancedMetaData/classes/class.ilAdvancedMDRecord.php');
35include_once('Services/AdvancedMetaData/classes/class.ilAdvancedMDFieldDefinition.php');
36
38{
39 const MODE_UPDATE = 1;
40 const MODE_INSERT = 2;
43
44 private $mode;
45
46 private $fields = array();
47
48 private $is_error = false;
49 private $error_msg = array();
50
51 protected $context; // [array]
52
53 protected $scopes = [];
54
55 protected $translations = [];
56 protected $translation_language = '';
57
58 protected $field_translations = [];
60
64 protected $log;
65
73 public function __construct($a_file)
74 {
75 parent::__construct($a_file, true);
76 $this->log = ilLoggerFactory::getLogger('amet');
77 }
78
86 public function setMode($a_mode)
87 {
88 $this->mode = $a_mode;
89 }
90
97 public function getMode()
98 {
99 return $this->mode;
100 }
101
102
110 public function startParsing()
111 {
112 parent::startParsing();
113 if ($this->is_error) {
114 include_once('./Services/Xml/exceptions/class.ilSaxParserException.php');
115 throw new ilSaxParserException(implode('<br/>', $this->error_msg));
116 }
117 }
118
125 public function setHandlers($a_xml_parser)
126 {
127 xml_set_object($a_xml_parser, $this);
128 xml_set_element_handler($a_xml_parser, 'handlerBeginTag', 'handlerEndTag');
129 xml_set_character_data_handler($a_xml_parser, 'handlerCharacterData');
130 }
131
137 protected function handlerBeginTag($a_xml_parser, $a_name, $a_attribs)
138 {
139 switch ($a_name) {
140 case 'AdvancedMetaDataRecords':
141 $this->is_error = false;
142 $this->error_msg = array();
143 // Nothing to do
144 break;
145
146 case 'Scope':
147 $this->scopes = [];
148 break;
149
150 case 'ScopeEntry':
151 $parsed_id = ilUtil::parseImportId($a_attribs['id']);
152 if (
153 $parsed_id['inst_id'] == IL_INST_ID &&
154 ilObject::_exists($parsed_id['id'], true, $parsed_id['type'])
155 ) {
156 $scope = new ilAdvancedMDRecordScope();
157 $scope->setRefId($parsed_id['id']);
158 $this->scopes[] = $scope;
159 }
160 break;
161
162
163 case 'Record':
164 $this->fields = array();
165 $this->current_field = null;
166 $this->current_record = null;
167 if (!strlen($a_attribs['id']) or !isset($a_attribs['active'])) {
168 $this->appendErrorMessage('Missing XML attribute for element "Record".');
169 }
170 if (!$this->initRecordObject($a_attribs['id'])) {
171 $this->appendErrorMessage('Invalid attribute Id given for element "Record".');
172 }
173 $this->getCurrentRecord()->setActive($a_attribs['active']);
174 $this->getCurrentRecord()->setImportId($a_attribs['id']);
175 $this->getCurrentRecord()->setAssignedObjectTypes(array());
176
177 if (isset($a_attribs['defaultLanguage'])) {
178 $language = (string) $a_attribs['defaultLanguage'];
179 if (ilLanguage::lookupId($language)) {
180 $this->getCurrentRecord()->setDefaultLanguage($language);
181 }
182 } else {
183 $this->getCurrentRecord()->setDefaultLanguage($this->lng->getDefaultLanguage());
184 }
185 break;
186
187 case 'RecordTranslations':
188 $this->translations = [];
189 $this->field_translations = [];
190 $this->getCurrentRecord()->setDefaultLanguage(
191 $a_attribs['defaultLanguage'] ?? $this->getCurrentRecord()->getDefaultLanguage()
192 );
193 break;
194
195 case 'RecordTranslation':
196 $this->translation_language = $a_attribs['language'] ?? $this->lng->getDefaultLanguage();
197 break;
198
199 case 'FieldTranslations':
200 $this->field_translations[$this->getCurrentField()->getImportId()] = [];
201 break;
202
203 case 'FieldTranslation':
204 $this->field_translation_language = $a_attribs['language'] ?? $this->lng->getDefaultLanguage();
205 break;
206
207 case 'Title':
208 break;
209
210 case 'Field':
211 if (!strlen($a_attribs['id']) or !isset($a_attribs['searchable']) or !isset($a_attribs['fieldType'])) {
212 $this->appendErrorMessage('Missing XML attribute for element "Field".');
213 }
214 if (!$this->initFieldObject($a_attribs['id'], $a_attribs['fieldType'])) {
215 $this->appendErrorMessage('Invalid attribute Id given for element "Record".');
216 }
217 $this->getCurrentField()->setImportId($a_attribs['id']);
218 $this->getCurrentField()->setSearchable($a_attribs['searchable'] == 'Yes' ? true : false);
219 break;
220
221 case 'FieldTitle':
222 case 'FieldDescription':
223 case 'FieldPosition':
224 case 'FieldValue':
225 $this->field_value_id = $a_attribs['id'];
226 break;
227 }
228 }
229
235 protected function handlerEndTag($a_xml_parser, $a_name)
236 {
237 switch ($a_name) {
238 case 'AdvancedMetaDataRecords':
239 break;
240
241 case 'Record':
242 $this->storeRecords();
243 break;
244
245 case 'Scope':
246 $this->getCurrentRecord()->setScopes($this->scopes);
247 break;
248
249 case 'Title':
250 $this->getCurrentRecord()->setTitle(trim($this->cdata));
251 break;
252
253 case 'Description':
254 $this->getCurrentRecord()->setDescription(trim($this->cdata));
255 break;
256
257 case 'ObjectType':
258 // #12980
259 $parts = explode(":", trim($this->cdata));
260 $this->getCurrentRecord()->appendAssignedObjectType($parts[0], $parts[1]);
261 break;
262
263 case 'Field':
264 break;
265
266 case 'RecordTranslationTitle':
267 $this->translations[$this->translation_language]['title'] = trim($this->cdata);
268 break;
269
270 case 'RecordTranslationDescription':
271 $this->translations[$this->translation_language]['description'] = trim($this->cdata);
272 break;
273
274 case 'FieldTranslationTitle':
275 $this->field_translations[$this->getCurrentField()->getImportId()][$this->field_translation_language]['title'] = trim($this->cdata);
276 break;
277
278 case 'FieldTranslationDescription':
279 $this->field_translations[$this->getCurrentField()->getImportId()][$this->field_translation_language]['description'] = trim($this->cdata);
280 break;
281
282 case 'FieldTitle':
283 $this->getCurrentField()->setTitle(trim($this->cdata));
284 break;
285
286 case 'FieldDescription':
287 $this->getCurrentField()->setDescription(trim($this->cdata));
288 break;
289
290 case 'FieldPosition':
291 $this->getCurrentField()->setPosition((int) trim($this->cdata));
292 break;
293
294 case 'FieldValue':
295 $this->getCurrentField()->importXMLProperty($this->field_value_id, trim($this->cdata));
296 break;
297 }
298 $this->cdata = '';
299 }
300
307 protected function handlerCharacterData($a_xml_parser, $a_data)
308 {
309 if ($a_data != "\n") {
310 // Replace multiple tabs with one space
311 $a_data = preg_replace("/\t+/", " ", $a_data);
312
313 $this->cdata .= $a_data;
314 }
315 }
316
324 private function initRecordObject($a_id)
325 {
326 switch ($this->getMode()) {
329 $this->current_record = new ilAdvancedMDRecord(0);
330 return true;
331
332 default:
333 $this->current_record = ilAdvancedMDRecord::_getInstanceByRecordId($this->extractRecordId($a_id));
334 return true;
335 break;
336 }
337 }
338
346 private function initFieldObject($a_id, $a_type)
347 {
348 switch ($this->getMode()) {
351 $this->current_field = ilAdvancedMDFieldDefinition::getInstanceByTypeString($a_type);
352 $this->fields[] = $this->current_field;
353 return true;
354
355 default:
356 // ??? nonsense
357 $this->current_field = ilAdvancedMDRecord::_getInstanceByFieldId($this->extractFieldId($a_id));
358 return true;
359 break;
360 }
361 }
362
367 {
368 return $this->current_record;
369 }
370
376 private function getCurrentField()
377 {
378 return $this->current_field;
379 }
380
388 private function extractRecordId($a_id_string)
389 {
390 // first lookup import id
391 if ($record_id = ilAdvancedMDRecord::_lookupRecordIdByImportId($a_id_string)) {
392 $this->record_exists = true;
393 return $record_id;
394 }
395 return 0;
396 }
397
398
399
407 private function appendErrorMessage($a_msg)
408 {
409 $this->is_error = true;
410 $this->error_msg[] = $a_msg;
411 }
412
420 private function storeRecords()
421 {
422 switch ($this->getMode()) {
425 return true;
426
428 // set local context
429 if (is_array($this->context)) {
430 $this->getCurrentRecord()->setParentObject($this->context["obj_id"]);
431 $this->getCurrentRecord()->setAssignedObjectTypes(array(
432 array(
433 "obj_type" => $this->context["obj_type"],
434 "sub_type" => $this->context["sub_type"],
435 "optional" => false
436 )));
437 }
438
439 $this->getCurrentRecord()->save();
440 break;
441 }
442 foreach ($this->fields as $field) {
443 $field->setRecordId($this->getCurrentRecord()->getRecordId());
444 switch ($this->getMode()) {
446 $field->save();
447 foreach ($this->field_translations as $field_id => $field_info) {
448 if (strcmp($field_id, $field->getImportId()) !== 0) {
449 continue;
450 }
451 foreach ((array) $field_info as $language => $field_translation) {
452 $translation = new ilAdvancedMDFieldTranslation(
453 (int) $field->getFieldId(),
454 (string) $field_translation['title'],
455 (string) $field_translation['description'],
456 (string) $language
457 );
458 $translation->insert();
459 }
460 }
461
462 // see getRecordMap()
463 $this->log->debug("add to record map, rec id: " . $this->getCurrentRecord()->getRecordId() .
464 ", import id: " . $field->getImportId() . ", field id:" . $field->getFieldId());
465 $this->rec_map[$this->getCurrentRecord()->getRecordId()][$field->getImportId()] = $field->getFieldId();
466 break;
467 }
468 }
470 $translations->addTranslationEntry($this->getCurrentRecord()->getDefaultLanguage(), true);
471 $translations->updateTranslations(
472 $this->getCurrentRecord()->getDefaultLanguage(),
473 (string) $this->getCurrentRecord()->getTitle(),
474 (string) $this->getCurrentRecord()->getDescription()
475 );
476
477 foreach ($this->translations as $lang_key => $translation_info) {
478 ilLoggerFactory::getLogger('root')->dump($translation_info, ilLogLevel::ERROR);
479 if (!$translations->isConfigured($lang_key)) {
480 $translations->addTranslationEntry($lang_key);
481 }
482 $translations->updateTranslations(
483 $lang_key,
484 (string) $translation_info['title'],
485 (string) $translation_info['description']
486 );
487 }
488
489 }
490
491 public function setContext($a_obj_id, $a_obj_type, $a_sub_type = null)
492 {
493 if (!$a_sub_type) {
494 $a_sub_type = "-";
495 }
496
497 $this->context = array(
498 "obj_id" => $a_obj_id,
499 "obj_type" => $a_obj_type,
500 "sub_type" => $a_sub_type
501 );
502 }
503
504 public function getRecordMap()
505 {
506 return $this->rec_map;
507 }
508}
An exception for terminatinating execution or to throw for unit testing.
static getInstanceByTypeString($a_type)
Get instance by type string (used by import)
Class ilAdvancedMDFieldTranslation.
SAX based XML parser for record import files.
initRecordObject($a_id)
Init record object.
setContext($a_obj_id, $a_obj_type, $a_sub_type=null)
handlerBeginTag($a_xml_parser, $a_name, $a_attribs)
Handler for start tags.
initFieldObject($a_id, $a_type)
Init field definition object.
setHandlers($a_xml_parser)
set event handlers
startParsing()
stores xml data in array
handlerEndTag($a_xml_parser, $a_name)
Handler for end tags.
handlerCharacterData($a_xml_parser, $a_data)
handler for character data
extractRecordId($a_id_string)
Extract id.
getCurrentField()
get current field definition @access private
Scope restrictions for advanced md records.
static _getInstanceByRecordId($a_record_id)
Get instance by record id.
static _lookupRecordIdByImportId($a_ilias_id)
Lookup record Id by import id.
static lookupId($a_lang_key)
Lookup obj_id of language @global ilDB $ilDB.
static getLogger($a_component_id)
Get component logger.
static _exists($a_id, $a_reference=false, $a_type=null)
checks if an object exists in object_data@access public
SaxParserException thrown by ilSaxParser if property throwException is set.
Base class for sax-based expat parsing extended classes need to overwrite the method setHandlers and ...
static parseImportId($a_import_id)
Parse an ilias import id Typically of type il_[IL_INST_ID]_[OBJ_TYPE]_[OBJ_ID] returns array( 'orig' ...
const IL_INST_ID
Definition: constants.php:38
$errors fields
Definition: imgupload.php:51
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc