ILIAS  release_8 Revision v8.24
class.ilMDSaxParser.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
30{
31 protected bool $md_in_md = false;
32 protected string $md_chr_data = '';
33 protected ?ilMDIdentifier $md_ide = null;
34 protected ?ilMDLanguage $md_lan = null;
35 protected ?ilMDDescription $md_des = null;
36 protected ?ilMDLifecycle $md_lif = null;
37 protected ?ilMDContribute $md_con = null;
38 protected ?ilMDEntity $md_ent = null;
39 protected ?ilMDMetaMetadata $md_met = null;
40 protected ?ilMDTechnical $md_tec = null;
41 protected ?ilMDFormat $md_for = null;
42 protected ?ilMDLocation $md_loc = null;
43 protected ?ilMDRequirement $md_req = null;
44 protected ?ilMDOrComposite $md_orc = null;
45 protected ?ilMDEducational $md_edu = null;
46 protected ?ilMDTypicalAgeRange $md_typ = null;
47 protected ?ilMDRights $md_rig = null;
48 protected ?ilMDRelation $md_rel = null;
49 protected ?ilMDIdentifier_ $md_ide_ = null;
50 protected ?ilMDAnnotation $md_ann = null;
51 protected ?ilMDClassification $md_cla = null;
52 protected ?ilMDTaxonPath $md_taxp = null;
53 protected ?ilMDTaxon $md_tax = null;
54 protected ?ilMDKeyword $md_key = null;
55
60 protected array $md_parent = array();
61
62 private bool $md_parsing_enabled;
63
64 protected ?ilMD $md = null;
65
66 protected ?ilMDGeneral $md_gen = null;
67
69
70 public function __construct(?string $a_xml_file = '')
71 {
72 global $DIC;
73
74 $this->meta_log = $DIC->logger()->meta();
75
76 // Enable parsing. E.g qpl' s will set this value to false
77 $this->md_parsing_enabled = true;
78
79 parent::__construct($a_xml_file);
80 }
81
82 public function enableMDParsing(bool $a_status): void
83 {
84 $this->md_parsing_enabled = $a_status;
85 }
86
87 public function getMDParsingStatus(): bool
88 {
90 }
91
92 public function setMDObject(ilMD $md): void
93 {
94 $this->md = $md;
95 }
96
97 public function getMDObject(): ?ilMD
98 {
99 return is_object($this->md) ? $this->md : null;
100 }
101
102 public function inMetaData(): bool
103 {
104 return $this->md_in_md;
105 }
106
111 public function setHandlers($a_xml_parser): void
112 {
113 xml_set_object($a_xml_parser, $this);
114 xml_set_element_handler($a_xml_parser, 'handlerBeginTag', 'handlerEndTag');
115 xml_set_character_data_handler($a_xml_parser, 'handlerCharacterData');
116 }
117
121 public function handlerBeginTag($a_xml_parser, string $a_name, array $a_attribs): void
122 {
123 $a_attribs = $this->trimAndStripAttribs($a_attribs);
124 if (!$this->getMDParsingStatus()) {
125 return;
126 }
127
128 switch ($a_name) {
129 case 'MetaData':
130 $this->md_in_md = true;
131 $this->__pushParent($this->md);
132 break;
133
134 case 'General':
135 $this->md_gen = $this->md->addGeneral();
136 $this->md_gen->setStructure($a_attribs['Structure'] ?? '');
137 $this->md_gen->save();
138 $this->__pushParent($this->md_gen);
139 break;
140
141 case 'Identifier':
142 $par = $this->__getParent();
143 $this->md_ide = $par->addIdentifier();
144 $this->md_ide->setCatalog($a_attribs['Catalog'] ?? '');
145 $this->md_ide->setEntry($a_attribs['Entry'] ?? '');
146 $this->md_ide->save();
147 $this->__pushParent($this->md_ide);
148 break;
149
150 case 'Title':
151 $par = $this->__getParent();
152 $par->setTitleLanguage(new ilMDLanguageItem($a_attribs['Language'] ?? ''));
153 break;
154
155 case 'Language':
156 $par = $this->__getParent();
157 $this->md_lan = $par->addLanguage();
158 $this->md_lan->setLanguage(new ilMDLanguageItem($a_attribs['Language'] ?? ''));
159 $this->md_lan->save();
160 $this->__pushParent($this->md_lan);
161 break;
162
163 case 'Description':
164 $par = $this->__getParent();
165
166 if (strtolower(get_class($par)) === 'ilmdrights' ||
167 strtolower(get_class($par)) === 'ilmdannotation' ||
168 strtolower(get_class($par)) === 'ilmdclassification') {
169 $par->setDescriptionLanguage(new ilMDLanguageItem($a_attribs['Language'] ?? ''));
170 break;
171 } else {
172 $this->md_des = $par->addDescription();
173 $this->md_des->setDescriptionLanguage(new ilMDLanguageItem($a_attribs['Language'] ?? ''));
174 $this->md_des->save();
175 $this->__pushParent($this->md_des);
176 break;
177 }
178
179 // no break
180 case 'Keyword':
181 $par = $this->__getParent();
182 if (!$par instanceof ilMD) {
183 $this->md_key = $par->addKeyword();
184 $this->md_key->setKeywordLanguage(new ilMDLanguageItem($a_attribs['Language'] ?? ''));
185 $this->md_key->save();
186 $this->__pushParent($this->md_key);
187 }
188 break;
189
190 case 'Coverage':
191 $par = $this->__getParent();
192 $par->setCoverageLanguage(new ilMDLanguageItem($a_attribs['Language'] ?? ''));
193 break;
194
195 case 'Lifecycle':
196 $par = $this->__getParent();
197 $this->md_lif = $par->addLifecycle();
198 $this->md_lif->setStatus($a_attribs['Status'] ?? '');
199 $this->md_lif->save();
200 $this->__pushParent($this->md_lif);
201 break;
202
203 case 'Version':
204 $par = $this->__getParent();
205 $par->setVersionLanguage(new ilMDLanguageItem($a_attribs['Language'] ?? ''));
206 break;
207
208 case 'Contribute':
209 $par = $this->__getParent();
210 $this->md_con = $par->addContribute();
211 $this->md_con->setRole($a_attribs['Role'] ?? '');
212 $this->md_con->save();
213 $this->__pushParent($this->md_con);
214 break;
215
216 case 'Entity':
217 $par = $this->__getParent();
218
219 if (strtolower(get_class($par)) === 'ilmdcontribute') {
220 $this->md_ent = $par->addEntity();
221 $this->md_ent->save();
222 $this->__pushParent($this->md_ent);
223 break;
224 } else {
225 // single element in 'Annotation'
226 break;
227 }
228 // no break
229 case 'Date':
230 break;
231
232 case 'Meta-Metadata':
233 $par = $this->__getParent();
234 $this->md_met = $par->addMetaMetadata();
235 $this->md_met->setMetaDataScheme($a_attribs['MetadataScheme'] ?? '');
236 $this->md_met->setLanguage(new ilMDLanguageItem((string) ($a_attribs['Language'] ?? "")));
237 $this->md_met->save();
238 $this->__pushParent($this->md_met);
239 break;
240
241 case 'Technical':
242 $par = $this->__getParent();
243 $this->md_tec = $par->addTechnical();
244 $this->md_tec->save();
245 $this->__pushParent($this->md_tec);
246 break;
247
248 case 'Format':
249 $par = $this->__getParent();
250 $this->md_for = $par->addFormat();
251 $this->md_for->save();
252 $this->__pushParent($this->md_for);
253 break;
254
255 case 'Size':
256 break;
257
258 case 'Location':
259 $par = $this->__getParent();
260 $this->md_loc = $par->addLocation();
261 $this->md_loc->setLocationType($a_attribs['Type'] ?? '');
262 $this->md_loc->save();
263 $this->__pushParent($this->md_loc);
264 break;
265
266 case 'Requirement':
267 $par = $this->__getParent();
268 $this->md_req = $par->addRequirement();
269 $this->md_req->save();
270 $this->__pushParent($this->md_req);
271 break;
272
273 case 'OrComposite':
274 $par = $this->__getParent();
275 $this->md_orc = $par->addOrComposite();
276 $this->__pushParent($this->md_orc);
277 break;
278
279 case 'Type':
280 break;
281
282 case 'OperatingSystem':
283 $par = $this->__getParent();
284 $par->setOperatingSystemName($a_attribs['Name'] ?? '');
285 $par->setOperatingSystemMinimumVersion($a_attribs['MinimumVersion'] ?? '');
286 $par->setOperatingSystemMaximumVersion($a_attribs['MaximumVersion'] ?? '');
287 break;
288
289 case 'Browser':
290 $par = $this->__getParent();
291 $par->setBrowserName($a_attribs['Name'] ?? '');
292 $par->setBrowserMinimumVersion($a_attribs['MinimumVersion'] ?? '');
293 $par->setBrowserMaximumVersion($a_attribs['MaximumVersion'] ?? '');
294 break;
295
296 case 'InstallationRemarks':
297 $par = $this->__getParent();
298 $par->setInstallationRemarksLanguage(new ilMDLanguageItem($a_attribs['Language'] ?? ''));
299 break;
300
301 case 'OtherPlatformRequirements':
302 $par = $this->__getParent();
303 $par->setOtherPlatformRequirementsLanguage(new ilMDLanguageItem($a_attribs['Language'] ?? ''));
304 break;
305
306 case 'Duration':
307 break;
308
309 case 'Educational':
310 $par = $this->__getParent();
311 $this->md_edu = $par->addEducational();
312 $this->md_edu->setInteractivityType($a_attribs['InteractivityType'] ?? '');
313 $this->md_edu->setLearningResourceType($a_attribs['LearningResourceType'] ?? '');
314 $this->md_edu->setInteractivityLevel($a_attribs['InteractivityLevel'] ?? '');
315 $this->md_edu->setSemanticDensity($a_attribs['SemanticDensity'] ?? '');
316 $this->md_edu->setIntendedEndUserRole($a_attribs['IntendedEndUserRole'] ?? '');
317 $this->md_edu->setContext($a_attribs['Context'] ?? '');
318 $this->md_edu->setDifficulty($a_attribs['Difficulty'] ?? '');
319 $this->md_edu->save();
320 $this->__pushParent($this->md_edu);
321 break;
322
323 case 'TypicalAgeRange':
324 $par = $this->__getParent();
325 $this->md_typ = $par->addTypicalAgeRange();
326 $this->md_typ->setTypicalAgeRangeLanguage(new ilMDLanguageItem($a_attribs['Language'] ?? ''));
327 $this->md_typ->save();
328 $this->__pushParent($this->md_typ);
329 break;
330
331 case 'TypicalLearningTime':
332 break;
333
334 case 'Rights':
335 $par = $this->__getParent();
336 $this->md_rig = $par->addRights();
337 $this->md_rig->setCosts($a_attribs['Cost'] ?? '');
338 $this->md_rig->setCopyrightAndOtherRestrictions($a_attribs['CopyrightAndOtherRestrictions'] ?? '');
339 $this->md_rig->save();
340 $this->__pushParent($this->md_rig);
341 break;
342
343 case 'Relation':
344 $par = $this->__getParent();
345 $this->md_rel = $par->addRelation();
346 $this->md_rel->setKind($a_attribs['Kind'] ?? '');
347 $this->md_rel->save();
348 $this->__pushParent($this->md_rel);
349 break;
350
351 case 'Resource':
352 break;
353
354 case 'Identifier_':
355 $par = $this->__getParent();
356 $this->md_ide_ = $par->addIdentifier_();
357 $this->md_ide_->setCatalog($a_attribs['Catalog'] ?? '');
358 $this->md_ide_->setEntry($a_attribs['Entry'] ?? '');
359 $this->md_ide_->save();
360 $this->__pushParent($this->md_ide_);
361 break;
362
363 case 'Annotation':
364 $par = $this->__getParent();
365 $this->md_ann = $par->addAnnotation();
366 $this->md_ann->save();
367 $this->__pushParent($this->md_ann);
368 break;
369
370 case 'Classification':
371 $par = $this->__getParent();
372 $this->md_cla = $par->addClassification();
373 $this->md_cla->setPurpose($a_attribs['Purpose'] ?? '');
374 $this->md_cla->save();
375 $this->__pushParent($this->md_cla);
376 break;
377
378 case 'TaxonPath':
379 $par = $this->__getParent();
380 $this->md_taxp = $par->addTaxonPath();
381 $this->md_taxp->save();
382 $this->__pushParent($this->md_taxp);
383 break;
384
385 case 'Source':
386 $par = $this->__getParent();
387 $par->setSourceLanguage(new ilMDLanguageItem($a_attribs['Language'] ?? ''));
388 break;
389
390 case 'Taxon':
391 $par = $this->__getParent();
392 $this->md_tax = $par->addTaxon();
393 $this->md_tax->setTaxonLanguage(new ilMDLanguageItem($a_attribs['Language'] ?? ''));
394 $this->md_tax->setTaxonId($a_attribs['Id'] ?? '');
395 $this->md_tax->save();
396 $this->__pushParent($this->md_tax);
397 break;
398 }
399 }
400
404 public function handlerEndTag($a_xml_parser, string $a_name): void
405 {
406 if (!$this->getMDParsingStatus()) {
407 return;
408 }
409
410 switch ($a_name) {
411 case 'MetaData':
412 $this->md_parent = array();
413 $this->md_in_md = false;
414 break;
415
416 case 'General':
417 $par = $this->__getParent();
418 $par->update();
419 $this->__popParent();
420 break;
421
422 case 'Identifier':
423 $par = $this->__getParent();
424 $par->update();
425 $this->__popParent();
426 break;
427
428 case 'Title':
429 $par = $this->__getParent();
430 $par->setTitle($this->__getCharacterData());
431 break;
432
433 case 'Language':
434 $par = $this->__getParent();
435 $par->update();
436 $this->__popParent();
437 break;
438
439 case 'Description':
440 $par = $this->__getParent();
441 if ($par instanceof ilMDRights) {
442 $par->parseDescriptionFromImport(
443 $this->__getCharacterData()
444 );
445 } else {
446 $par->setDescription($this->__getCharacterData());
447 }
448 $par->update();
449 if ($par instanceof ilMDDescription) {
450 $this->__popParent();
451 }
452 break;
453
454 case 'Keyword':
455 $par = $this->__getParent();
456 if (!$par instanceof ilMD) {
457 $par->setKeyword($this->__getCharacterData());
458 $this->meta_log->debug("Keyword: " . $this->__getCharacterData());
459 $par->update();
460 $this->__popParent();
461 }
462 break;
463
464 case 'Coverage':
465 $par = $this->__getParent();
466 $par->setCoverage($this->__getCharacterData());
467 break;
468
469 case 'Lifecycle':
470 $par = $this->__getParent();
471 $par->update();
472 $this->__popParent();
473 break;
474
475 case 'Version':
476 $par = $this->__getParent();
477 $par->setVersion($this->__getCharacterData());
478 break;
479
480 case 'Contribute':
481 $par = $this->__getParent();
482 $par->update();
483 $this->__popParent();
484 break;
485
486 case 'Entity':
487 $par = $this->__getParent();
488
489 if (strtolower(get_class($par)) === 'ilmdentity') {
490 $par->setEntity($this->__getCharacterData());
491 $par->update();
492 $this->__popParent();
493 } else {
494 // Single element in 'Annotation'
495 $par->setEntity($this->__getCharacterData());
496 }
497 break;
498
499 case 'Date':
500 $par = $this->__getParent();
501 $par->setDate($this->__getCharacterData());
502 break;
503
504 case 'Meta-Metadata':
505 $par = $this->__getParent();
506 $par->update();
507 $this->__popParent();
508 break;
509
510 case 'Technical':
511 $par = $this->__getParent();
512 $par->update();
513 $this->__popParent();
514 break;
515
516 case 'Format':
517 $par = $this->__getParent();
518 $par->setFormat($this->__getCharacterData());
519 $par->update();
520 $this->__popParent();
521 break;
522
523 case 'Size':
524 $par = $this->__getParent();
525 $par->setSize($this->__getCharacterData());
526 break;
527
528 case 'Location':
529 $par = $this->__getParent();
530 $par->setLocation($this->__getCharacterData());
531 $par->update();
532 $this->__popParent();
533 break;
534
535 case 'Requirement':
536 $par = $this->__getParent();
537 $par->update();
538 $this->__popParent();
539 break;
540
541 case 'OrComposite':
542 $this->__popParent();
543 break;
544
545 case 'Type':
546 break;
547
548 case 'OperatingSystem':
549 break;
550
551 case 'Browser':
552 break;
553
554 case 'InstallationRemarks':
555 $par = $this->__getParent();
556 $par->setInstallationRemarks($this->__getCharacterData());
557 break;
558
559 case 'OtherPlatformRequirements':
560 $par = $this->__getParent();
561 $par->setOtherPlatformRequirements($this->__getCharacterData());
562 break;
563
564 case 'Duration':
565 $par = $this->__getParent();
566 $par->setDuration($this->__getCharacterData());
567 break;
568
569 case 'Educational':
570 $par = $this->__getParent();
571 $par->update();
572 $this->__popParent();
573 break;
574
575 case 'TypicalAgeRange':
576 $par = $this->__getParent();
577 $par->setTypicalAgeRange($this->__getCharacterData());
578 $par->update();
579 $this->__popParent();
580 break;
581
582 case 'TypicalLearningTime':
583 $par = $this->__getParent();
584 $par->setTypicalLearningTime($this->__getCharacterData());
585 break;
586
587 case 'Rights':
588 $par = $this->__getParent();
589 $par->update();
590 $this->__popParent();
591 break;
592
593 case 'Relation':
594 $par = $this->__getParent();
595 $par->update();
596 $this->__popParent();
597 break;
598
599 case 'Resource':
600 break;
601
602 case 'Identifier_':
603 $par = $this->__getParent();
604 $par->update();
605 $this->__popParent();
606 break;
607
608 case 'Annotation':
609 $par = $this->__getParent();
610 $par->update();
611 $this->__popParent();
612 break;
613
614 case 'Classification':
615 $par = $this->__getParent();
616 $par->update();
617 $this->__popParent();
618 break;
619
620 case 'TaxonPath':
621 $par = $this->__getParent();
622 $par->update();
623 $this->__popParent();
624 break;
625
626 case 'Taxon':
627 $par = $this->__getParent();
628 $par->setTaxon($this->__getCharacterData());
629 $par->update();
630 $this->__popParent();
631 break;
632
633 case 'Source':
634 $par = $this->__getParent();
635 $par->setSource($this->__getCharacterData());
636 break;
637
638 }
639 $this->md_chr_data = '';
640 }
641
645 public function handlerCharacterData($a_xml_parser, string $a_data): void
646 {
647 if (!$this->getMDParsingStatus()) {
648 return;
649 }
650
651 if ($a_data !== "\n" && $this->inMetaData()) {
652 // Replace multiple tabs with one space
653 $a_data = preg_replace("/\t+/", " ", $a_data);
654
655 $this->md_chr_data .= $a_data;
656 }
657 }
658
659 // PRIVATE
660 public function __getCharacterData(): string
661 {
662 return $this->trimAndStrip($this->md_chr_data);
663 }
664
665 public function __pushParent(object $md_obj): void
666 {
667 $this->md_parent[] = &$md_obj;
668 $this->meta_log->debug('New parent stack (push)...');
669 foreach ($this->md_parent as $class) {
670 $this->meta_log->debug(get_class($class));
671 }
672 }
673
674 public function __popParent(): void
675 {
676 $this->meta_log->debug('New parent stack (pop)....');
677 $class = array_pop($this->md_parent);
678 foreach ((array) $this->md_parent as $class) {
679 $this->meta_log->debug(get_class($class));
680 }
681 $this->meta_log->debug(is_object($class) ? get_class($class) : 'null');
682 unset($class);
683 }
684
685 public function __getParent(): object
686 {
687 return $this->md_parent[count($this->md_parent) - 1];
688 }
689
690 protected function trimAndStripAttribs(array $attribs): array
691 {
692 $ret = [];
693 foreach ($attribs as $k => $v) {
694 $ret[$k] = $this->trimAndStrip((string) $v);
695 }
696 return $ret;
697 }
698
699 protected function trimAndStrip(string $input): string
700 {
701 return ilUtil::stripSlashes(trim($input));
702 }
703}
Component logger with individual log levels by component id.
ilMDRelation $md_rel
ilMDLanguage $md_lan
trimAndStrip(string $input)
ilMDDescription $md_des
ilMDTypicalAgeRange $md_typ
enableMDParsing(bool $a_status)
ilMDLocation $md_loc
ilMDIdentifier_ $md_ide_
ilMDTaxonPath $md_taxp
__pushParent(object $md_obj)
ilMDClassification $md_cla
ilMDOrComposite $md_orc
trimAndStripAttribs(array $attribs)
handlerCharacterData($a_xml_parser, string $a_data)
handlerEndTag($a_xml_parser, string $a_name)
ilMDTechnical $md_tec
ilMDRequirement $md_req
ilMDAnnotation $md_ann
setHandlers($a_xml_parser)
Set event handlers.
ilMDIdentifier $md_ide
ilMDMetaMetadata $md_met
__construct(?string $a_xml_file='')
ilMDContribute $md_con
ilMDLifecycle $md_lif
handlerBeginTag($a_xml_parser, string $a_name, array $a_attribs)
ilMDEducational $md_edu
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
global $DIC
Definition: feed.php:28
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc