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