Passed
Pull Request — master (#1205)
by Osma
04:18
created

VocabularyConfig::getSortByNotation()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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

397
        return $this->getLiteral('skosmos:marcSourceCode', /** @scrutinizer ignore-type */ false, $lang);
Loading history...
398
    }
399
400
    /**
401
     * Returns a boolean value set in the config.ttl config.
402
     * @return array array of concept class URIs (can be empty)
403
     */
404
    public function getIndexClasses()
405
    {
406
        return $this->getResources("skosmos:indexShowClass");
407
    }
408
409
    /**
410
     * Returns skosmos:externalProperty values set in the config.ttl config.
411
     * @return array array of external property URIs (can be empty)
412
     */
413
    public function getExtProperties()
414
    {
415
        return $this->getResources("skosmos:externalProperty");
416
    }
417
418
    /**
419
     * Get the languages supported by this vocabulary
420
     * @return array languages supported by this vocabulary (as language tag strings)
421
     */
422
    public function getLanguages()
423
    {
424
        $langs = $this->resource->allLiterals('skosmos:language');
425
        $ret = array();
426
        foreach ($langs as $lang) {
427
            $langlit = Punic\Language::getName($lang->getValue(), $this->getEnvLang());
428
            $ret[$langlit] = $lang->getValue();
429
        }
430
        ksort($ret);
431
432
        return $ret;
433
    }
434
435
    /**
436
     * Returns the plugin parameters
437
     * @return string plugin parameters or null
438
     */
439
    public function getPluginParameters() {
440
        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

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

632
                /** @scrutinizer ignore-call */ 
633
                $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...
633
                $ret[] = ($short !== null) ? $short : $prop->getURI();
634
            }
635
            return $ret;
636
        }
637
        
638
        trigger_error("Property order for vocabulary '{$this->getShortName()}' unknown, using default order", E_USER_WARNING);
639
        return self::DEFAULT_PROPERTY_ORDER;
640
    }
641
}
642