ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
SimpleDC.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
31use ILIAS\Data\Factory as DataFactory;
32
33class 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}
Builds data types.
Definition: Factory.php:36
__construct()
Constructor setup ILIAS global object @access public.
Definition: class.ilias.php:76
$path
Definition: ltiservices.php:30
FilterType
Values should always be all lowercase.
Definition: FilterType.php:27
if(!file_exists('../ilias.ini.php'))