ILIAS  trunk Revision v11.0_alpha-1715-g7fc467680fb
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
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;
37  protected ?ilMDLifecycle $md_lif = null;
38  protected ?ilMDContribute $md_con = null;
39  protected ?ilMDEntity $md_ent = null;
41  protected ?ilMDTechnical $md_tec = null;
42  protected ?ilMDFormat $md_for = null;
43  protected ?ilMDLocation $md_loc = null;
48  protected ?ilMDRights $md_rig = null;
49  protected ?ilMDRelation $md_rel = null;
51  protected ?ilMDAnnotation $md_ann = 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_element_handler($a_xml_parser, $this->handlerBeginTag(...), $this->handlerEndTag(...));
115  xml_set_character_data_handler($a_xml_parser, $this->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  $this->md_chr_data = '';
639  }
640 
644  public function handlerCharacterData($a_xml_parser, string $a_data): void
645  {
646  if (!$this->getMDParsingStatus()) {
647  return;
648  }
649 
650  if ($a_data !== "\n" && $this->inMetaData()) {
651  // Replace multiple tabs with one space
652  $a_data = preg_replace("/\t+/", " ", $a_data);
653 
654  $this->md_chr_data .= $a_data;
655  }
656  }
657 
658  // PRIVATE
659  public function __getCharacterData(): string
660  {
661  return $this->trimAndStrip($this->md_chr_data);
662  }
663 
664  public function __pushParent(object $md_obj): void
665  {
666  $this->md_parent[] = &$md_obj;
667  $this->meta_log->debug('New parent stack (push)...');
668  foreach ($this->md_parent as $class) {
669  $this->meta_log->debug(get_class($class));
670  }
671  }
672 
673  public function __popParent(): void
674  {
675  $this->meta_log->debug('New parent stack (pop)....');
676  $class = array_pop($this->md_parent);
677  foreach ((array) $this->md_parent as $class) {
678  $this->meta_log->debug(get_class($class));
679  }
680  $this->meta_log->debug(is_object($class) ? get_class($class) : 'null');
681  unset($class);
682  }
683 
684  public function __getParent(): object
685  {
686  return $this->md_parent[count($this->md_parent) - 1];
687  }
688 
689  protected function trimAndStripAttribs(array $attribs): array
690  {
691  $ret = [];
692  foreach ($attribs as $k => $v) {
693  $ret[$k] = $this->trimAndStrip((string) $v);
694  }
695  return $ret;
696  }
697 
698  protected function trimAndStrip(string $input): string
699  {
700  return ilUtil::stripSlashes(trim($input));
701  }
702 }
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...
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
handlerCharacterData($a_xml_parser, string $a_data)
ilMDDescription $md_des
ilMDLocation $md_loc
ilMDRequirement $md_req
global $DIC
Definition: shib_login.php:22
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