ILIAS  trunk Revision v11.0_alpha-1769-g99a433fe2dc
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
SimpleDC.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
32 
33 class SimpleDC implements SimpleDCInterface
34 {
35  protected PathFactory $path_factory;
36  protected NavigatorFactoryInterface $navigator_factory;
37  protected DataFactory $data_factory;
38  protected CopyrightHandlerInterface $copyright_handler;
39  protected LinkGeneratorInterface $link_generator;
40 
41  public function __construct(
42  PathFactory $path_factory,
43  NavigatorFactoryInterface $navigator_factory,
44  DataFactory $data_factory,
45  CopyrightHandlerInterface $copyright_handler,
46  LinkGeneratorInterface $link_generator
47  ) {
48  $this->path_factory = $path_factory;
49  $this->navigator_factory = $navigator_factory;
50  $this->data_factory = $data_factory;
51  $this->copyright_handler = $copyright_handler;
52  $this->link_generator = $link_generator;
53  }
54 
55  public function write(
56  SetInterface $set,
57  int $object_ref_id
58  ): \SimpleXMLElement {
59  $xml = new \SimpleXMLElement(<<<XML
60  <oai_dc:dc
61  xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
62  xmlns:dc="http://purl.org/dc/elements/1.1/"
63  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
64  xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
65  </oai_dc:dc>
66  XML);
67 
68  $this->addTitleToXML($xml, $set);
69  $this->addCreatorsPublishersAndContributorsToXML($xml, $set);
70  $this->addSubjectsToXML($xml, $set);
71  $this->addDescriptionsToXML($xml, $set);
72  $this->addDateToXML($xml, $set);
73  $this->addTypesToXML($xml, $set);
74  $this->addFormatsToXML($xml, $set);
75  $this->addIdentifierToXML($xml, $set, $object_ref_id);
76  $this->addSourcesAndRelationsToXML($xml, $set);
77  $this->addLanguagesToXML($xml, $set);
78  $this->addCoveragesToXML($xml, $set);
79  $this->addRightsToXML($xml, $set);
80 
81  return $xml;
82  }
83 
84  protected function addTitleToXML(\SimpleXMLElement $xml, SetInterface $set): void
85  {
86  $title_path = $this->path_factory
87  ->custom()
88  ->withNextStep('general')
89  ->withNextStep('title')
90  ->get();
91 
92  $this->addLangStringsToXML($xml, $set, 'title', $title_path);
93  }
94 
95  protected function addCreatorsPublishersAndContributorsToXML(\SimpleXMLElement $xml, SetInterface $set): void
96  {
97  $creator_path = $this->path_factory
98  ->custom()
99  ->withNextStep('lifeCycle')
100  ->withNextStep('contribute')
101  ->withNextStep('role')
102  ->withNextStep('value')
103  ->withAdditionalFilterAtCurrentStep(FilterType::DATA, 'author')
104  ->withNextStepToSuperElement()
105  ->withNextStepToSuperElement()
106  ->withNextStep('entity')
107  ->get();
108 
109  $publisher_path = $this->path_factory
110  ->custom()
111  ->withNextStep('lifeCycle')
112  ->withNextStep('contribute')
113  ->withNextStep('role')
114  ->withNextStep('value')
115  ->withAdditionalFilterAtCurrentStep(FilterType::DATA, 'publisher')
116  ->withNextStepToSuperElement()
117  ->withNextStepToSuperElement()
118  ->withNextStep('entity')
119  ->get();
120 
121  $any_contributor_path = $this->path_factory
122  ->custom()
123  ->withNextStep('lifeCycle')
124  ->withNextStep('contribute')
125  ->withNextStep('entity')
126  ->get();
127 
128  $path_from_entity_to_role = $this->path_factory
129  ->custom()
130  ->withRelative(true)
131  ->withNextStepToSuperElement()
132  ->withNextStep('role')
133  ->withNextStep('value')
134  ->get();
135 
136  $creators = [];
137  $creator_navigator = $this->navigator_factory->navigator($creator_path, $set->getRoot());
138  foreach ($creator_navigator->elementsAtFinalStep() as $creator) {
139  $creators[] = $creator;
140  $this->addNamespacedChildToXML(
141  $xml,
142  'creator',
143  $creator->getData()->value()
144  );
145  }
146 
147  $publishers = [];
148  $publisher_navigator = $this->navigator_factory->navigator($publisher_path, $set->getRoot());
149  foreach ($publisher_navigator->elementsAtFinalStep() as $publisher) {
150  $publishers[] = $publisher;
151  $this->addNamespacedChildToXML(
152  $xml,
153  'publisher',
154  $publisher->getData()->value()
155  );
156  }
157 
158  $any_contributor_navigator = $this->navigator_factory->navigator($any_contributor_path, $set->getRoot());
159  foreach ($any_contributor_navigator->elementsAtFinalStep() as $any_contributor) {
160  if (
161  in_array($any_contributor, $creators, true) ||
162  in_array($any_contributor, $publishers, true)
163  ) {
164  continue;
165  }
166 
167  $role = $this->navigator_factory
168  ->navigator($path_from_entity_to_role, $any_contributor)
169  ->lastElementAtFinalStep()?->getData()?->value() ?? '';
170  $contributor = $any_contributor->getData()->value();
171  if ($role !== '') {
172  $contributor .= ' (' . $role . ')';
173  }
174  $this->addNamespacedChildToXML(
175  $xml,
176  'contributor',
177  $contributor
178  );
179  }
180  }
181 
182  protected function addSubjectsToXML(\SimpleXMLElement $xml, SetInterface $set): void
183  {
184  $keyword_path = $this->path_factory
185  ->custom()
186  ->withNextStep('general')
187  ->withNextStep('keyword')
188  ->get();
189 
190  $this->addLangStringsToXML($xml, $set, 'subject', $keyword_path);
191 
192  $taxon_entry_string_path = $this->path_factory
193  ->custom()
194  ->withNextStep('classification')
195  ->withNextStep('purpose')
196  ->withNextStep('value')
197  ->withAdditionalFilterAtCurrentStep(FilterType::DATA, 'discipline')
198  ->withNextStepToSuperElement()
199  ->withNextStepToSuperElement()
200  ->withNextStep('taxonPath')
201  ->withNextStep('taxon')
202  ->withNextStep('entry')
203  ->withNextStep('string')
204  ->get();
205 
206  $navigator = $this->navigator_factory->navigator($taxon_entry_string_path, $set->getRoot());
207  $strings = [];
208  $current_taxon_path = null;
209 
210  foreach ($navigator->elementsAtFinalStep() as $entry_string) {
211  $taxon_path = $entry_string->getSuperElement()->getSuperElement()->getSuperElement();
212  if ($current_taxon_path !== $taxon_path) {
213  if (!empty($strings)) {
214  $this->addNamespacedChildToXML($xml, 'subject', implode(': ', $strings));
215  }
216 
217  $current_taxon_path = $taxon_path;
218  $strings = [];
219  }
220 
221  if ($entry_string->getData()->value() !== '') {
222  $strings[] = $entry_string->getData()->value();
223  }
224  }
225 
226  if (!empty($strings)) {
227  $this->addNamespacedChildToXML($xml, 'subject', implode(': ', $strings));
228  }
229  }
230 
231  protected function addDescriptionsToXML(\SimpleXMLElement $xml, SetInterface $set): void
232  {
233  $description_path = $this->path_factory
234  ->custom()
235  ->withNextStep('general')
236  ->withNextStep('description')
237  ->get();
238 
239  $this->addLangStringsToXML($xml, $set, 'description', $description_path);
240  }
241 
242  protected function addDateToXML(\SimpleXMLElement $xml, SetInterface $set): void
243  {
244  $date_path = $this->path_factory
245  ->custom()
246  ->withNextStep('lifeCycle')
247  ->withNextStep('contribute')
248  ->withNextStep('date')
249  ->withAdditionalFilterAtCurrentStep(FilterType::INDEX, '0')
250  ->get();
251 
252  foreach ($this->getDataValuesFromPath($set, $date_path) as $value) {
253  $this->addNamespacedChildToXML($xml, 'date', $value);
254  }
255  }
256 
257  protected function addTypesToXML(\SimpleXMLElement $xml, SetInterface $set): void
258  {
259  $type_path = $this->path_factory
260  ->custom()
261  ->withNextStep('educational')
262  ->withNextStep('learningResourceType')
263  ->withNextStep('value')
264  ->get();
265 
266  foreach ($this->getDataValuesFromPath($set, $type_path) as $value) {
267  $this->addNamespacedChildToXML($xml, 'type', $value);
268  }
269  }
270 
271  protected function addFormatsToXML(\SimpleXMLElement $xml, SetInterface $set): void
272  {
273  $format_path = $this->path_factory
274  ->custom()
275  ->withNextStep('technical')
276  ->withNextStep('format')
277  ->get();
278 
279  foreach ($this->getDataValuesFromPath($set, $format_path) as $value) {
280  $this->addNamespacedChildToXML($xml, 'format', $value);
281  }
282  }
283 
284  protected function addIdentifierToXML(
285  \SimpleXMLElement $xml,
286  SetInterface $set,
287  int $object_ref_id
288  ): void {
289  $type = $set->getRessourceID()->type();
290  if ($type === '') {
291  return;
292  }
293 
294  $link = $this->link_generator->generateLinkForReference($object_ref_id, $type);
295  $this->addNamespacedChildToXML($xml, 'identifier', (string) $link);
296 
297  if (!$this->link_generator->doesReferenceHavePublicAccessExport($object_ref_id)) {
298  return;
299  }
300  $download_link = $this->link_generator->generateLinkForPublicAccessExportOfReference($object_ref_id);
301  $this->addNamespacedChildToXML($xml, 'identifier', (string) $download_link);
302  }
303 
304  protected function addLanguagesToXML(\SimpleXMLElement $xml, SetInterface $set): void
305  {
306  $language_path = $this->path_factory
307  ->custom()
308  ->withNextStep('general')
309  ->withNextStep('language')
310  ->get();
311 
312  foreach ($this->getDataValuesFromPath($set, $language_path) as $value) {
313  $this->addNamespacedChildToXML(
314  $xml,
315  'language',
316  $value === 'xx' ? 'none' : $value
317  );
318  }
319  }
320 
321  protected function addSourcesAndRelationsToXML(\SimpleXMLElement $xml, SetInterface $set): void
322  {
323  $source_path = $this->path_factory
324  ->custom()
325  ->withNextStep('relation')
326  ->withNextStep('kind')
327  ->withNextStep('value')
328  ->withAdditionalFilterAtCurrentStep(FilterType::DATA, 'isbasedon')
329  ->withNextStepToSuperElement()
330  ->withNextStepToSuperElement()
331  ->withNextStep('resource')
332  ->withNextStep('identifier')
333  ->withNextStep('entry')
334  ->get();
335 
336  $any_entry_path = $this->path_factory
337  ->custom()
338  ->withNextStep('relation')
339  ->withNextStep('resource')
340  ->withNextStep('identifier')
341  ->withNextStep('entry')
342  ->get();
343 
344  $sources = [];
345  $source_navigator = $this->navigator_factory->navigator($source_path, $set->getRoot());
346  foreach ($source_navigator->elementsAtFinalStep() as $source) {
347  $sources[] = $source;
348  $this->addNamespacedChildToXML(
349  $xml,
350  'source',
351  $source->getData()->value()
352  );
353  }
354 
355  $any_entry_navigator = $this->navigator_factory->navigator($any_entry_path, $set->getRoot());
356  foreach ($any_entry_navigator->elementsAtFinalStep() as $any_entry) {
357  if (in_array($any_entry, $sources, true)) {
358  continue;
359  }
360 
361  $this->addNamespacedChildToXML(
362  $xml,
363  'relation',
364  $any_entry->getData()->value()
365  );
366  }
367  }
368 
369  protected function addCoveragesToXML(\SimpleXMLElement $xml, SetInterface $set): void
370  {
371  $coverage_path = $this->path_factory
372  ->custom()
373  ->withNextStep('general')
374  ->withNextStep('coverage')
375  ->get();
376 
377  $this->addLangStringsToXML($xml, $set, 'coverage', $coverage_path);
378  }
379 
380  protected function addRightsToXML(\SimpleXMLElement $xml, SetInterface $set): void
381  {
382  $description_path = $this->path_factory
383  ->custom()
384  ->withNextStep('rights')
385  ->withNextStep('description')
386  ->withNextStep('string')
387  ->get();
388 
389  foreach ($this->getDataValuesFromPath($set, $description_path) as $value) {
390  $this->addNamespacedChildToXML(
391  $xml,
392  'rights',
393  $this->copyright_handler->copyrightAsString($value)
394  );
395  }
396  }
397 
398  protected function addLangStringsToXML(
399  \SimpleXMLElement $xml,
400  SetInterface $set,
401  string $name,
402  PathInterface $path
403  ): void {
404  $navigator = $this->navigator_factory->navigator($path, $set->getRoot());
405  foreach ($navigator->elementsAtFinalStep() as $element) {
406  $string_element = null;
407  $lang_element = null;
408  foreach ($element->getSubElements() as $sub_element) {
409  if ($sub_element->getDefinition()->name() === 'string') {
410  $string_element = $sub_element;
411  }
412  if ($sub_element->getDefinition()->name() === 'language') {
413  $lang_element = $sub_element;
414  }
415  }
416 
417  if (is_null($string_element)) {
418  continue;
419  }
420  $string_xml = $this->addNamespacedChildToXML(
421  $xml,
422  $name,
423  $string_element->getData()->value()
424  );
425  if (!is_null($lang_element) && !is_null($string_xml)) {
426  $string_xml->addAttribute(
427  'xml:lang',
428  $lang_element->getData()->value(),
429  'xml'
430  );
431  }
432  }
433  }
434 
438  protected function getDataValuesFromPath(SetInterface $set, PathInterface $path): \Generator
439  {
440  $navigator = $this->navigator_factory->navigator($path, $set->getRoot());
441  foreach ($navigator->elementsAtFinalStep() as $element) {
442  yield $element->getData()->value();
443  }
444  }
445 
446  protected function addNamespacedChildToXML(
447  \SimpleXMLElement $xml,
448  string $name,
449  string $value
450  ): ?\SimpleXMLElement {
451  if ($value === '') {
452  return null;
453  }
454  $child_xml = $xml->addChild($name, null, "http://purl.org/dc/elements/1.1/");
455  $child_xml[0] = $value;
456  return $child_xml;
457  }
458 }
FilterType
Values should always be all lowercase.
Definition: FilterType.php:26
$path
Definition: ltiservices.php:29
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
__construct()
Constructor setup ILIAS global object public.
Definition: class.ilias.php:76
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...