Passed
Pull Request — master (#1198)
by
unknown
04:08
created

VocabularyConfig::getExternalResourcesLoading()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * VocabularyConfig provides access to the vocabulary configuration defined in config.ttl.
5
 */
6
class VocabularyConfig extends BaseConfig
7
{
8
    private $plugins;
9
    private $pluginParameters;
10
    private $languageOrderCache = array();
11
12
    const DEFAULT_PROPERTY_ORDER = array("rdf:type", "dc:isReplacedBy",
13
    "skos:definition", "skos:broader", "isothes:broaderGeneric",
14
    "isothes:broaderPartitive", "isothes:broaderInstantial",
15
    "skos:narrower", "isothes:narrowerGeneric", "isothes:narrowerPartitive",
16
    "isothes:narrowerInstantial", "skos:related", "skos:altLabel",
17
    "skos:note", "skos:scopeNote", "skos:historyNote", "rdfs:comment",
18
    "dc11:source", "dc:source", "skosmos:memberOf", "skosmos:memberOfArray");
19
20
    const ISO25964_PROPERTY_ORDER = array("rdf:type", "dc:isReplacedBy",
21
    // ISO 25964 allows placing all text fields (inc. SN and DEF) together
22
    // so we will do that, except for HN, which is clearly administrative
23
    "skos:note", "skos:scopeNote", "skos:definition", "rdfs:comment",
24
    "dc11:source", "dc:source", "skos:altLabel", "skos:broader",
25
    "isothes:broaderGeneric", "isothes:broaderPartitive",
26
    "isothes:broaderInstantial", "skos:narrower", "isothes:narrowerGeneric",
27
    "isothes:narrowerPartitive", "isothes:narrowerInstantial",
28
    "skos:related", "skos:historyNote", "skosmos:memberOf",
29
    "skosmos:memberOfArray");
30
31
    public function __construct($resource, $globalPlugins=array())
32
    {
33
        $this->resource = $resource;
34
        $plugins = $this->resource->allLiterals('skosmos:usePlugin');
35
        $pluginArray = array();
36
        if ($plugins) {
37
            foreach ($plugins as $pluginlit) {
38
                $pluginArray[] = $pluginlit->getValue();
39
            }
40
        }
41
        $this->plugins = new PluginRegister(array_merge($globalPlugins, $pluginArray));
42
        // Get parameterized plugins defined as resources and their respective parameters
43
        $pluginResources = $this->resource->allResources('skosmos:useParamPlugin');
44
        $this->pluginParameters = array();
45
        if ($pluginResources) {
46
            foreach ($pluginResources as $pluginResource) {
47
                $pluginName = $pluginResource->getLiteral('skosmos:usePlugin')->getValue();
48
                $this->pluginParameters[$pluginName] = array();
49
50
                $pluginParams = $pluginResource->allResources('skosmos:parameters');
51
                foreach ($pluginParams as $parameter) {
52
53
                    $paramLiterals = $parameter->allLiterals('schema:value');
54
                    foreach ($paramLiterals as $paramLiteral) {
55
                        $paramName = $parameter->getLiteral('schema:propertyID')->getValue();
56
                        $paramValue = $paramLiteral->getValue();
57
                        $paramLang = $paramLiteral->getLang();
58
                        if ($paramLang) {
59
                            $paramName .= '_' . $paramLang;
60
                        }
61
                        $this->pluginParameters[$pluginName][$paramName] = $paramValue;
62
                    }
63
                }
64
                $pluginArray[] = $pluginName;
65
            }
66
            $this->plugins = new PluginRegister(array_merge($globalPlugins, $pluginArray));
67
        }
68
69
    }
70
71
    /**
72
     * Get the SPARQL endpoint URL for this vocabulary
73
     *
74
     * @return string|null endpoint URL, or null if not set
75
     */
76
    public function getSparqlEndpoint()
77
    {
78
        $endpoint = $this->resource->get('void:sparqlEndpoint');
79
        if ($endpoint) {
80
            return $endpoint->getUri();
81
        }
82
        return null;
83
    }
84
85
    /**
86
     * Get the SPARQL graph URI for this vocabulary
87
     *
88
     * @return string|null graph URI, or null if not set
89
     */
90
    public function getSparqlGraph()
91
    {
92
        $graph = $this->resource->get('skosmos:sparqlGraph');
93
        if ($graph) {
94
            $graph = $graph->getUri();
95
        }
96
97
        return $graph;
98
    }
99
100
    /**
101
     * Get the SPARQL dialect for this vocabulary
102
     *
103
     * @return string|null dialect name
104
     */
105
    public function getSparqlDialect()
106
    {
107
        $dialect = $this->resource->get('skosmos:sparqlDialect');
108
        if ($dialect) {
109
            $dialect = $dialect->getValue();
110
        }
111
112
        return $dialect;
113
    }
114
115
    /**
116
     * Get the default language of this vocabulary
117
     * @return string default language, e.g. 'en'
118
     */
119
120
    public function getDefaultLanguage()
121
    {
122
        $deflang = $this->resource->getLiteral('skosmos:defaultLanguage');
123
        if ($deflang) {
0 ignored issues
show
introduced by
$deflang is of type EasyRdf\Literal, thus it always evaluated to true.
Loading history...
124
            return $deflang->getValue();
125
        }
126
127
        $langs = $this->getLanguages();
128
        $deflang = reset($langs); // picking the first one from the list with reset since the keys are not numeric
129
        if (sizeof($langs) > 1) {
130
            trigger_error("Default language for vocabulary '" . $this->getShortName() . "' unknown, choosing '$deflang'.", E_USER_WARNING);
131
        }
132
133
        return $deflang;
134
    }
135
136
    /**
137
     * Whether the alphabetical index is small enough to be shown all at once.
138
     * @return boolean true if all concepts can be shown at once.
139
     */
140
    public function getAlphabeticalFull()
141
    {
142
        return $this->getBoolean('skosmos:fullAlphabeticalIndex');
143
    }
144
145
    /**
146
     * Returns a short name for a vocabulary if configured. If that has not been set
147
     * using vocabId as a fallback.
148
     * @return string
149
     */
150
    public function getShortName()
151
    {
152
        $shortname = $this->getLiteral('skosmos:shortName');
153
        if ($shortname)
154
          return $shortname;
155
156
        // if no shortname exists fall back to the id
157
        return $this->getId();
158
    }
159
160
    /**
161
     * Get the vocabulary feedback e-mail address and return it.
162
     *
163
     * @return string e-mail address or null if not defined.
164
     */
165
    public function getFeedbackRecipient()
166
    {
167
        $email = $this->resource->get('skosmos:feedbackRecipient');
168
        return isset($email) ? $email->getValue() : null;
169
    }
170
171
    /**
172
     * Returns the human readable vocabulary title.
173
     * @return string the title of the vocabulary
174
     */
175
    public function getTitle($lang = null)
176
    {
177
        return $this->getLiteral('dc:title', false, $lang);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $default of BaseConfig::getLiteral(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

177
        return $this->getLiteral('dc:title', /** @scrutinizer ignore-type */ false, $lang);
Loading history...
178
    }
179
180
    /**
181
     * Returns the sorting strategy for notation codes set in the config.ttl
182
     * config: either "lexical", "natural", or null if sorting by notations is 
183
     * disabled. A "true" value in the configuration file is interpreted as
184
     * "lexical".
185
     * @return string|bool
186
     */
187
    public function getSortByNotation(): ?string
188
    {
189
        $value = $this->getLiteral('skosmos:sortByNotation');
190
        if ($value == "lexical" || $value == "natural") {
191
            return $value;
192
        }
193
        // not a special value - interpret as boolean instead
194
        $bvalue = $this->getBoolean('skosmos:sortByNotation');
195
        // "true" is interpreted as "lexical"
196
        return $bvalue ? "lexical" : null;
197
    }
198
199
    /**
200
     * Returns a boolean value set in the config.ttl config.
201
     * @return boolean
202
     */
203
    public function showChangeList()
204
    {
205
        return $this->getBoolean('skosmos:showChangeList');
206
    }
207
208
    /**
209
     * get the URLs from which the vocabulary data can be downloaded
210
     * @return array Array with MIME type as key, URL as value
211
     */
212
    public function getDataURLs()
213
    {
214
        $ret = array();
215
        $urls = $this->resource->allResources("void:dataDump");
216
        foreach ($urls as $url) {
217
            // first try dc:format and dc11:format
218
            $mimetypelit = $url->getLiteral('dc:format');
219
            if ($mimetypelit === null) {
220
                $mimetypelit = $url->getLiteral('dc11:format');
221
            }
222
223
            if ($mimetypelit !== null) {
224
                $mimetype = $mimetypelit->getValue();
225
            } else {
226
                $format = EasyRdf\Format::guessFormat(null, $url->getURI());
227
                if ($format === null) {
228
                    trigger_error("Could not guess format for <$url>.", E_USER_WARNING);
229
                    continue;
230
                }
231
                $mimetypes = array_keys($format->getMimeTypes());
232
                $mimetype = $mimetypes[0];
233
            }
234
235
            $langLit = $url->getLiteral('dc:language');
236
237
            if ($langLit != null) {
238
                //when the mimetype has language variants
239
                $dataUrlLang = $langLit->getValue();
240
241
                if (!isset($ret[$mimetype])) {
242
                  $arr = array();
243
                } else {
244
                  $arr = $ret[$mimetype];
245
                }
246
                $arr[$dataUrlLang] = $url->getURI();
247
                $ret[$mimetype] = $arr;
248
            } else {
249
                $ret[$mimetype] = $url->getURI();
250
            }
251
        }
252
        return $ret;
253
    }
254
255
    /**
256
     * Returns the main Concept Scheme URI of that Vocabulary,
257
     * or null if not set.
258
     * @return string concept scheme URI or null
259
     */
260
261
    public function getMainConceptSchemeURI()
262
    {
263
        $val = $this->resource->getResource("skosmos:mainConceptScheme");
264
        if ($val) {
0 ignored issues
show
introduced by
$val is of type EasyRdf\Resource, thus it always evaluated to true.
Loading history...
265
            return $val->getURI();
266
        }
267
268
        return null;
269
    }
270
271
    /**
272
     * Returns the class URI used for concept groups in this vocabulary,
273
     * or null if not set.
274
     * @return string group class URI or null
275
     */
276
277
    public function getGroupClassURI()
278
    {
279
        $val = $this->resource->getResource("skosmos:groupClass");
280
        if ($val) {
0 ignored issues
show
introduced by
$val is of type EasyRdf\Resource, thus it always evaluated to true.
Loading history...
281
            return $val->getURI();
282
        }
283
284
        return null;
285
    }
286
287
    /**
288
     * Returns the class URI used for thesaurus arrays in this vocabulary,
289
     * or null if not set.
290
     * @return string array class URI or null
291
     */
292
293
    public function getArrayClassURI()
294
    {
295
        $val = $this->resource->getResource("skosmos:arrayClass");
296
        if ($val) {
0 ignored issues
show
introduced by
$val is of type EasyRdf\Resource, thus it always evaluated to true.
Loading history...
297
            return $val->getURI();
298
        }
299
300
        return null;
301
    }
302
303
    /**
304
     * Returns custom properties displayed on the search page if configured.
305
     * @return array array class URI or null
306
     */
307
308
    public function getAdditionalSearchProperties()
309
    {
310
        $resources = $this->resource->allResources("skosmos:showPropertyInSearch");
311
        $ret = array();
312
        foreach ($resources as $res) {
313
            $prop = $res->getURI();
314
            if (EasyRdf\RdfNamespace::shorten($prop) !== null) // shortening property labels if possible
315
            {
316
                $prop = EasyRdf\RdfNamespace::shorten($prop);
317
            }
318
319
            $ret[] = $prop;
320
        }
321
        return $ret;
322
    }
323
324
    /**
325
     * Queries whether the property should be shown with all the label language variations.
326
     * @param string $property
327
     * @return boolean
328
     */
329
    public function hasMultiLingualProperty($property)
330
    {
331
        $resources = $this->resource->allResources("skosmos:hasMultiLingualProperty");
332
        foreach ($resources as $res) {
333
            $prop = $res->getURI();
334
            if (EasyRdf\RdfNamespace::shorten($prop) !== null) // shortening property labels if possible
335
            {
336
                $prop = EasyRdf\RdfNamespace::shorten($prop);
337
            }
338
339
            if ($prop === $property) {
340
                return true;
341
            }
342
343
        }
344
        return false;
345
    }
346
347
    /**
348
     * Returns a boolean value set in the config.ttl config.
349
     * @return boolean
350
     */
351
    public function getShowHierarchy()
352
    {
353
        return $this->getBoolean('skosmos:showTopConcepts');
354
    }
355
356
    /**
357
     * Returns a boolean value set in the config.ttl config.
358
     * @return boolean
359
     */
360
    public function showConceptSchemesInHierarchy()
361
    {
362
        return $this->getBoolean('skosmos:conceptSchemesInHierarchy');
363
    }
364
365
    /**
366
     * Returns a boolean value set in the config.ttl config.
367
     * @return boolean defaults to true if fetching hasn't been explicitly denied.
368
     */
369
    public function getExternalResourcesLoading()
370
    {
371
        return $this->getBoolean('skosmos:loadExternalResources', true);
372
    }
373
374
    /**
375
     * Returns a boolean value set in the config.ttl config.
376
     * @return boolean
377
     */
378
    public function getShowLangCodes()
379
    {
380
        return $this->getBoolean('skosmos:explicitLanguageTags');
381
    }
382
383
    /**
384
     * Returns a boolean value set in the config.ttl config.
385
     * @return boolean
386
     */
387
    public function searchByNotation()
388
    {
389
        return $this->getBoolean('skosmos:searchByNotation');
390
    }
391
392
    /**
393
     * Returns skosmos:marcSourcecode value set in config.ttl.
394
     * @return string marcsource name
395
     */
396
    public function getMarcSourceCode($lang = null)
397
    {
398
        return $this->getLiteral('skosmos:marcSourceCode', false, $lang);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $default of BaseConfig::getLiteral(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

398
        return $this->getLiteral('skosmos:marcSourceCode', /** @scrutinizer ignore-type */ false, $lang);
Loading history...
399
    }
400
401
    /**
402
     * Returns the boolean value of the skosmos:showNotationAsProperty setting.
403
     * @return boolean
404
     */
405
    public function getShowNotationAsProperty()
406
    {
407
        return $this->getBoolean('skosmos:showNotationAsProperty', true);
408
    }
409
410
    /**
411
     * Returns a boolean value set in the config.ttl config.
412
     * @return array array of concept class URIs (can be empty)
413
     */
414
    public function getIndexClasses()
415
    {
416
        return $this->getResources("skosmos:indexShowClass");
417
    }
418
419
    /**
420
     * Returns skosmos:externalProperty values set in the config.ttl config.
421
     * @return array array of external property URIs (can be empty)
422
     */
423
    public function getExtProperties()
424
    {
425
        return $this->getResources("skosmos:externalProperty");
426
    }
427
428
    /**
429
     * Get the languages supported by this vocabulary
430
     * @return array languages supported by this vocabulary (as language tag strings)
431
     */
432
    public function getLanguages()
433
    {
434
        $langs = $this->resource->allLiterals('skosmos:language');
435
        $ret = array();
436
        foreach ($langs as $lang) {
437
            $langlit = Punic\Language::getName($lang->getValue(), $this->getEnvLang());
438
            $ret[$langlit] = $lang->getValue();
439
        }
440
        ksort($ret);
441
442
        return $ret;
443
    }
444
445
    /**
446
     * Returns the plugin parameters
447
     * @return string plugin parameters or null
448
     */
449
    public function getPluginParameters() {
450
        return json_encode($this->pluginParameters, true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type integer expected by parameter $flags of json_encode(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

450
        return json_encode($this->pluginParameters, /** @scrutinizer ignore-type */ true);
Loading history...
451
    }
452
453
    /**
454
     * Returns the vocabulary default sidebar view.
455
     * @return string name of the view
456
     */
457
    public function getDefaultSidebarView()
458
    {
459
        $defview = $this->resource->getLiteral('skosmos:defaultSidebarView');
460
        if ($defview) {
0 ignored issues
show
introduced by
$defview is of type EasyRdf\Literal, thus it always evaluated to true.
Loading history...
461
            $value = $defview->getValue();
462
            if ($value === 'groups' || $value === 'hierarchy') {
463
                return $value;
464
            }
465
466
        }
467
        if ($this->showAlphabeticalIndex() === false) {
468
            if ($this->getShowHierarchy()) {
469
                return 'hierarchy';
470
            } else if ($this->getGroupClassURI()) {
471
                return 'groups';
472
            }
473
        }
474
        return 'alphabetical'; // if not defined displaying the alphabetical index
475
    }
476
477
    /**
478
     * Extracts the vocabulary id string from the baseuri of the vocabulary.
479
     * @return string identifier eg. 'mesh'.
480
     */
481
    public function getId()
482
    {
483
        $uriparts = explode("#", $this->resource->getURI());
484
        if (count($uriparts) != 1)
485
        // hash namespace
486
        {
487
            return $uriparts[1];
488
        }
489
490
        // slash namespace
491
        $uriparts = explode("/", $this->resource->getURI());
492
493
        return $uriparts[count($uriparts) - 1];
494
    }
495
496
    public function getShowStatistics() {
497
        return $this->getBoolean('skosmos:showStatistics', true);
498
    }
499
500
    public function getPlugins()
501
    {
502
        return $this->plugins;
503
    }
504
505
    /**
506
     * Returns the property/properties used for visualizing concept hierarchies.
507
     * @return array array class URI or null
508
     */
509
510
    public function getHierarchyProperty()
511
    {
512
        $resources = $this->resource->allResources("skosmos:hierarchyProperty");
513
        $ret = array();
514
        foreach ($resources as $res) {
515
            $prop = $res->getURI();
516
            if (EasyRdf\RdfNamespace::shorten($prop) !== null) // prefixing if possible
517
            {
518
                $prop = EasyRdf\RdfNamespace::shorten($prop);
519
            }
520
521
            $ret[] = $prop;
522
        }
523
        return empty($ret) ? array('skos:broader') : $ret;
524
    }
525
526
    /**
527
     * Returns a boolean value set in the config.ttl config.
528
     * @return boolean
529
     */
530
    public function showNotation()
531
    {
532
        return $this->getBoolean('skosmos:showNotation', true);
533
    }
534
535
    /**
536
     * Returns a boolean value set in the config.ttl config.
537
     * @return boolean
538
     */
539
    public function showAlphabeticalIndex()
540
    {
541
        return $this->getBoolean('skosmos:showAlphabeticalIndex', true);
542
    }
543
544
    /**
545
     * Returns the alphabetical list qualifier in this vocabulary,
546
     * or null if not set.
547
     * @return EasyRdf\Resource|null alphabetical list qualifier resource or null
548
     */
549
    public function getAlphabeticalListQualifier()
550
    {
551
        return $this->resource->getResource('skosmos:alphabeticalListQualifier');
552
    }
553
554
    /**
555
     * Returns a boolean value set in the config.ttl config.
556
     * @return boolean
557
     */
558
    public function getShowDeprecated()
559
    {
560
        return $this->getBoolean('skosmos:showDeprecated', false);
561
    }
562
563
    /**
564
     * Returns the vocabulary dc:type value(s) with their labels and uris, if set in the vocabulary configuration.
565
     * @return array of objects or an empty array
566
     */
567
    public function getTypes($lang = null)
568
    {
569
        $resources = $this->resource->allResources("dc:type");
570
        $ret = array();
571
        foreach ($resources as $res) {
572
            $prop = $res->getURI();
573
            $label = $res->label($lang) ? $res->label($lang) : $res->label($this->getDefaultLanguage());
574
            $ret[] = array('uri' => $prop, 'prefLabel' =>  $label->getValue());
575
        }
576
        return $ret;
577
    }
578
579
    /**
580
     * Returns an array of fallback languages that is ordered by priority and
581
     * defined in the vocabulary configuration as a collection.
582
     * Additionally, the chosen content language is inserted with the highest priority
583
     * and the vocab default language is inserted with the lowest priority.
584
     * @param string $clang
585
     * @return array of language code strings
586
     */
587
    public function getLanguageOrder($clang)
588
    {
589
        if (array_key_exists($clang, $this->languageOrderCache)) {
590
            return $this->languageOrderCache[$clang];
591
        }
592
        $ret = array($clang);
593
        $fallbacks = !empty($this->resource->get('skosmos:fallbackLanguages')) ? $this->resource->get('skosmos:fallbackLanguages') : array();
594
        foreach ($fallbacks as $lang) {
595
            if (!in_array($lang, $ret)) {
596
                $ret[] = (string)$lang; // Literal to string conversion
597
            }
598
        }
599
        if (!in_array($this->getDefaultLanguage(), $ret)) {
600
            $ret[] = (string)$this->getDefaultLanguage();
601
        }
602
        foreach ($this->getLanguages() as $lang) {
603
            if (!in_array($lang, $ret)) {
604
                $ret[] = $lang;
605
            }
606
        }
607
        // store in cache so this doesn't have to be computed again
608
        $this->languageOrderCache[$clang] = $ret;
609
        return $ret;
610
    }
611
612
    /**
613
     * @return boolean
614
     */
615
    public function isUseModifiedDate()
616
    {
617
        return $this->getBoolean('skosmos:useModifiedDate', false);
618
    }
619
620
    /**
621
     * @return array
622
     */
623
    public function getPropertyOrder()
624
    {
625
        $order = $this->getResource()->getResource('skosmos:propertyOrder');
626
        if ($order === null) {
627
            return self::DEFAULT_PROPERTY_ORDER;
628
        }
629
630
        $short = EasyRdf\RdfNamespace::shorten($order);
631
        if ($short == 'skosmos:iso25964PropertyOrder') {
632
            return self::ISO25964_PROPERTY_ORDER;
633
        } elseif ($short == 'skosmos:defaultPropertyOrder') {
634
            return self::DEFAULT_PROPERTY_ORDER;
635
        }
636
        
637
        // check for custom order definition
638
        $orderList = $order->getResource('rdf:value');
639
        if ($orderList !== null && $orderList instanceof EasyRdf\Collection) {
640
            $ret = array();
641
            foreach ($orderList as $prop) {
642
                $short = $prop->shorten();
0 ignored issues
show
Bug introduced by
The method shorten() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

642
                /** @scrutinizer ignore-call */ 
643
                $short = $prop->shorten();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
643
                $ret[] = ($short !== null) ? $short : $prop->getURI();
644
            }
645
            return $ret;
646
        }
647
        
648
        trigger_error("Property order for vocabulary '{$this->getShortName()}' unknown, using default order", E_USER_WARNING);
649
        return self::DEFAULT_PROPERTY_ORDER;
650
    }
651
}
652