Completed
Pull Request — master (#1166)
by Osma
02:23
created

VocabularyConfig::getSparqlGraph()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 9
rs 9.9666
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 endpoint URL
75
     */
76 View Code Duplication
    public function getSparqlEndpoint()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
77
    {
78
        $endpoint = $this->resource->get('void:sparqlEndpoint');
79
        if ($endpoint) {
80
            return $endpoint->getUri();
81
        } elseif (getenv('SKOSMOS_SPARQL_ENDPOINT')) {
82
            return getenv('SKOSMOS_SPARQL_ENDPOINT');
83
        } else {
84
            return 'http://localhost:3030/ds/sparql';
85
        }
86
    }
87
88
    /**
89
     * Get the SPARQL graph URI for this vocabulary
90
     *
91
     * @return string|null graph URI
92
     */
93
    public function getSparqlGraph()
94
    {
95
        $graph = $this->resource->get('skosmos:sparqlGraph');
96
        if ($graph) {
97
            $graph = $graph->getUri();
98
        }
99
100
        return $graph;
101
    }
102
103
    /**
104
     * Get the SPARQL dialect for this vocabulary
105
     *
106
     * @return string|null dialect name
107
     */
108
    public function getSparqlDialect()
109
    {
110
        $dialect = $this->resource->get('skosmos:sparqlDialect');
111
        if ($dialect) {
112
            $dialect = $dialect->getValue();
113
        }
114
115
        return $dialect;
116
    }
117
118
    /**
119
     * Get the default language of this vocabulary
120
     * @return string default language, e.g. 'en'
121
     */
122
123
    public function getDefaultLanguage()
124
    {
125
        $deflang = $this->resource->getLiteral('skosmos:defaultLanguage');
126
        if ($deflang) {
127
            return $deflang->getValue();
128
        }
129
130
        $langs = $this->getLanguages();
131
        $deflang = reset($langs); // picking the first one from the list with reset since the keys are not numeric
132
        if (sizeof($langs) > 1) {
133
            trigger_error("Default language for vocabulary '" . $this->getShortName() . "' unknown, choosing '$deflang'.", E_USER_WARNING);
134
        }
135
136
        return $deflang;
137
    }
138
139
    /**
140
     * Whether the alphabetical index is small enough to be shown all at once.
141
     * @return boolean true if all concepts can be shown at once.
142
     */
143
    public function getAlphabeticalFull()
144
    {
145
        return $this->getBoolean('skosmos:fullAlphabeticalIndex');
146
    }
147
148
    /**
149
     * Returns a short name for a vocabulary if configured. If that has not been set
150
     * using vocabId as a fallback.
151
     * @return string
152
     */
153
    public function getShortName()
154
    {
155
        $shortname = $this->getLiteral('skosmos:shortName');
156
        if ($shortname)
157
          return $shortname;
158
159
        // if no shortname exists fall back to the id
160
        return $this->getId();
161
    }
162
163
    /**
164
     * Get the vocabulary feedback e-mail address and return it.
165
     *
166
     * @return string e-mail address or null if not defined.
167
     */
168
    public function getFeedbackRecipient()
169
    {
170
        $email = $this->resource->get('skosmos:feedbackRecipient');
171
        return isset($email) ? $email->getValue() : null;
172
    }
173
174
    /**
175
     * Returns the human readable vocabulary title.
176
     * @return string the title of the vocabulary
177
     */
178
    public function getTitle($lang = null)
179
    {
180
        return $this->getLiteral('dc:title', false, $lang);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
181
    }
182
183
    /**
184
     * Returns a boolean value set in the config.ttl config.
185
     * @return boolean
186
     */
187
    public function sortByNotation()
188
    {
189
        return $this->getBoolean('skosmos:sortByNotation');
190
    }
191
192
    /**
193
     * Returns a boolean value set in the config.ttl config.
194
     * @return boolean
195
     */
196
    public function showChangeList()
197
    {
198
        return $this->getBoolean('skosmos:showChangeList');
199
    }
200
201
    /**
202
     * get the URLs from which the vocabulary data can be downloaded
203
     * @return array Array with MIME type as key, URL as value
204
     */
205
    public function getDataURLs()
206
    {
207
        $ret = array();
208
        $urls = $this->resource->allResources("void:dataDump");
209
        foreach ($urls as $url) {
210
            // first try dc:format and dc11:format
211
            $mimetypelit = $url->getLiteral('dc:format');
212
            if ($mimetypelit === null) {
213
                $mimetypelit = $url->getLiteral('dc11:format');
214
            }
215
216
            if ($mimetypelit !== null) {
217
                $mimetype = $mimetypelit->getValue();
218
            } else {
219
                $format = EasyRdf\Format::guessFormat(null, $url->getURI());
220
                if ($format === null) {
221
                    trigger_error("Could not guess format for <$url>.", E_USER_WARNING);
222
                    continue;
223
                }
224
                $mimetypes = array_keys($format->getMimeTypes());
225
                $mimetype = $mimetypes[0];
226
            }
227
228
            $langLit = $url->getLiteral('dc:language');
229
230
            if ($langLit != null) {
231
                //when the mimetype has language variants
232
                $dataUrlLang = $langLit->getValue();
233
234
                if (!isset($ret[$mimetype])) {
235
                  $arr = array();
236
                } else {
237
                  $arr = $ret[$mimetype];
238
                }
239
                $arr[$dataUrlLang] = $url->getURI();
240
                $ret[$mimetype] = $arr;
241
            } else {
242
                $ret[$mimetype] = $url->getURI();
243
            }
244
        }
245
        return $ret;
246
    }
247
248
    /**
249
     * Returns the main Concept Scheme URI of that Vocabulary,
250
     * or null if not set.
251
     * @return string concept scheme URI or null
252
     */
253
254
    public function getMainConceptSchemeURI()
255
    {
256
        $val = $this->resource->getResource("skosmos:mainConceptScheme");
257
        if ($val) {
258
            return $val->getURI();
259
        }
260
261
        return null;
262
    }
263
264
    /**
265
     * Returns the class URI used for concept groups in this vocabulary,
266
     * or null if not set.
267
     * @return string group class URI or null
268
     */
269
270
    public function getGroupClassURI()
271
    {
272
        $val = $this->resource->getResource("skosmos:groupClass");
273
        if ($val) {
274
            return $val->getURI();
275
        }
276
277
        return null;
278
    }
279
280
    /**
281
     * Returns the class URI used for thesaurus arrays in this vocabulary,
282
     * or null if not set.
283
     * @return string array class URI or null
284
     */
285
286
    public function getArrayClassURI()
287
    {
288
        $val = $this->resource->getResource("skosmos:arrayClass");
289
        if ($val) {
290
            return $val->getURI();
291
        }
292
293
        return null;
294
    }
295
296
    /**
297
     * Returns custom properties displayed on the search page if configured.
298
     * @return array array class URI or null
299
     */
300
301 View Code Duplication
    public function getAdditionalSearchProperties()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
302
    {
303
        $resources = $this->resource->allResources("skosmos:showPropertyInSearch");
304
        $ret = array();
305
        foreach ($resources as $res) {
306
            $prop = $res->getURI();
307
            if (EasyRdf\RdfNamespace::shorten($prop) !== null) // shortening property labels if possible
308
            {
309
                $prop = EasyRdf\RdfNamespace::shorten($prop);
310
            }
311
312
            $ret[] = $prop;
313
        }
314
        return $ret;
315
    }
316
317
    /**
318
     * Queries whether the property should be shown with all the label language variations.
319
     * @param string $property
320
     * @return boolean
321
     */
322
    public function hasMultiLingualProperty($property)
323
    {
324
        $resources = $this->resource->allResources("skosmos:hasMultiLingualProperty");
325
        foreach ($resources as $res) {
326
            $prop = $res->getURI();
327
            if (EasyRdf\RdfNamespace::shorten($prop) !== null) // shortening property labels if possible
328
            {
329
                $prop = EasyRdf\RdfNamespace::shorten($prop);
330
            }
331
332
            if ($prop === $property) {
333
                return true;
334
            }
335
336
        }
337
        return false;
338
    }
339
340
    /**
341
     * Returns a boolean value set in the config.ttl config.
342
     * @return boolean
343
     */
344
    public function getShowHierarchy()
345
    {
346
        return $this->getBoolean('skosmos:showTopConcepts');
347
    }
348
349
    /**
350
     * Returns a boolean value set in the config.ttl config.
351
     * @return boolean
352
     */
353
    public function showConceptSchemesInHierarchy()
354
    {
355
        return $this->getBoolean('skosmos:conceptSchemesInHierarchy');
356
    }
357
358
    /**
359
     * Returns a boolean value set in the config.ttl config.
360
     * @return boolean defaults to true if fetching hasn't been explicitly denied.
361
     */
362
    public function getExternalResourcesLoading()
363
    {
364
        return $this->getBoolean('skosmos:loadExternalResources', true);
365
    }
366
367
    /**
368
     * Returns a boolean value set in the config.ttl config.
369
     * @return boolean
370
     */
371
    public function getShowLangCodes()
372
    {
373
        return $this->getBoolean('skosmos:explicitLanguageTags');
374
    }
375
376
    /**
377
     * Returns a boolean value set in the config.ttl config.
378
     * @return boolean
379
     */
380
    public function searchByNotation()
381
    {
382
        return $this->getBoolean('skosmos:searchByNotation');
383
    }
384
385
    /**
386
     * Returns skosmos:marcSourcecode value set in config.ttl.
387
     * @return string marcsource name
388
     */
389
    public function getMarcSourceCode($lang = null)
390
    {
391
        return $this->getLiteral('skosmos:marcSourceCode', false, $lang);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
392
    }
393
394
    /**
395
     * Returns a boolean value set in the config.ttl config.
396
     * @return array array of concept class URIs (can be empty)
397
     */
398
    public function getIndexClasses()
399
    {
400
        return $this->getResources("skosmos:indexShowClass");
401
    }
402
403
    /**
404
     * Returns skosmos:externalProperty values set in the config.ttl config.
405
     * @return array array of external property URIs (can be empty)
406
     */
407
    public function getExtProperties()
408
    {
409
        return $this->getResources("skosmos:externalProperty");
410
    }
411
412
    /**
413
     * Get the languages supported by this vocabulary
414
     * @return array languages supported by this vocabulary (as language tag strings)
415
     */
416
    public function getLanguages()
417
    {
418
        $langs = $this->resource->allLiterals('skosmos:language');
419
        $ret = array();
420
        foreach ($langs as $lang) {
421
            $langlit = Punic\Language::getName($lang->getValue(), $this->getEnvLang());
422
            $ret[$langlit] = $lang->getValue();
423
        }
424
        ksort($ret);
425
426
        return $ret;
427
    }
428
429
    /**
430
     * Returns the plugin parameters
431
     * @return string plugin parameters or null
432
     */
433
    public function getPluginParameters() {
434
        return json_encode($this->pluginParameters, true);
435
    }
436
437
    /**
438
     * Returns the vocabulary default sidebar view.
439
     * @return string name of the view
440
     */
441
    public function getDefaultSidebarView()
442
    {
443
        $defview = $this->resource->getLiteral('skosmos:defaultSidebarView');
444
        if ($defview) {
445
            $value = $defview->getValue();
446
            if ($value === 'groups' || $value === 'hierarchy') {
447
                return $value;
448
            }
449
450
        }
451
        if ($this->showAlphabeticalIndex() === false) {
452
            if ($this->getShowHierarchy()) {
453
                return 'hierarchy';
454
            } else if ($this->getGroupClassURI()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->getGroupClassURI() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
455
                return 'groups';
456
            }
457
        }
458
        return 'alphabetical'; // if not defined displaying the alphabetical index
459
    }
460
461
    /**
462
     * Extracts the vocabulary id string from the baseuri of the vocabulary.
463
     * @return string identifier eg. 'mesh'.
464
     */
465
    public function getId()
466
    {
467
        $uriparts = explode("#", $this->resource->getURI());
468
        if (count($uriparts) != 1)
469
        // hash namespace
470
        {
471
            return $uriparts[1];
472
        }
473
474
        // slash namespace
475
        $uriparts = explode("/", $this->resource->getURI());
476
477
        return $uriparts[count($uriparts) - 1];
478
    }
479
480
    public function getShowStatistics() {
481
        return $this->getBoolean('skosmos:showStatistics', true);
482
    }
483
484
    public function getPlugins()
485
    {
486
        return $this->plugins;
487
    }
488
489
    /**
490
     * Returns the property/properties used for visualizing concept hierarchies.
491
     * @return array array class URI or null
492
     */
493
494 View Code Duplication
    public function getHierarchyProperty()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
495
    {
496
        $resources = $this->resource->allResources("skosmos:hierarchyProperty");
497
        $ret = array();
498
        foreach ($resources as $res) {
499
            $prop = $res->getURI();
500
            if (EasyRdf\RdfNamespace::shorten($prop) !== null) // prefixing if possible
501
            {
502
                $prop = EasyRdf\RdfNamespace::shorten($prop);
503
            }
504
505
            $ret[] = $prop;
506
        }
507
        return empty($ret) ? array('skos:broader') : $ret;
508
    }
509
510
    /**
511
     * Returns a boolean value set in the config.ttl config.
512
     * @return boolean
513
     */
514
    public function showNotation()
515
    {
516
        return $this->getBoolean('skosmos:showNotation', true);
517
    }
518
519
    /**
520
     * Returns a boolean value set in the config.ttl config.
521
     * @return boolean
522
     */
523
    public function showAlphabeticalIndex()
524
    {
525
        return $this->getBoolean('skosmos:showAlphabeticalIndex', true);
526
    }
527
528
    /**
529
     * Returns the alphabetical list qualifier in this vocabulary,
530
     * or null if not set.
531
     * @return EasyRdf\Resource|null alphabetical list qualifier resource or null
532
     */
533
    public function getAlphabeticalListQualifier()
534
    {
535
        return $this->resource->getResource('skosmos:alphabeticalListQualifier');
536
    }
537
538
    /**
539
     * Returns a boolean value set in the config.ttl config.
540
     * @return boolean
541
     */
542
    public function getShowDeprecated()
543
    {
544
        return $this->getBoolean('skosmos:showDeprecated', false);
545
    }
546
547
    /**
548
     * Returns the vocabulary dc:type value(s) with their labels and uris, if set in the vocabulary configuration.
549
     * @return array of objects or an empty array
550
     */
551
    public function getTypes($lang = null)
552
    {
553
        $resources = $this->resource->allResources("dc:type");
554
        $ret = array();
555
        foreach ($resources as $res) {
556
            $prop = $res->getURI();
557
            $label = $res->label($lang) ? $res->label($lang) : $res->label($this->getDefaultLanguage());
558
            $ret[] = array('uri' => $prop, 'prefLabel' =>  $label->getValue());
559
        }
560
        return $ret;
561
    }
562
563
    /**
564
     * Returns an array of fallback languages that is ordered by priority and
565
     * defined in the vocabulary configuration as a collection.
566
     * Additionally, the chosen content language is inserted with the highest priority
567
     * and the vocab default language is inserted with the lowest priority.
568
     * @param string $clang
569
     * @return array of language code strings
570
     */
571
    public function getLanguageOrder($clang)
572
    {
573
        if (array_key_exists($clang, $this->languageOrderCache)) {
574
            return $this->languageOrderCache[$clang];
575
        }
576
        $ret = array($clang);
577
        $fallbacks = !empty($this->resource->get('skosmos:fallbackLanguages')) ? $this->resource->get('skosmos:fallbackLanguages') : array();
578
        foreach ($fallbacks as $lang) {
579
            if (!in_array($lang, $ret)) {
580
                $ret[] = (string)$lang; // Literal to string conversion
581
            }
582
        }
583
        if (!in_array($this->getDefaultLanguage(), $ret)) {
584
            $ret[] = (string)$this->getDefaultLanguage();
585
        }
586
        foreach ($this->getLanguages() as $lang) {
587
            if (!in_array($lang, $ret)) {
588
                $ret[] = $lang;
589
            }
590
        }
591
        // store in cache so this doesn't have to be computed again
592
        $this->languageOrderCache[$clang] = $ret;
593
        return $ret;
594
    }
595
596
    /**
597
     * @return boolean
598
     */
599
    public function isUseModifiedDate()
600
    {
601
        return $this->getBoolean('skosmos:useModifiedDate', false);
602
    }
603
604
    /**
605
     * @return array
606
     */
607
    public function getPropertyOrder()
608
    {
609
        $order = $this->getResource()->getResource('skosmos:propertyOrder');
610
        if ($order === null) {
611
            return self::DEFAULT_PROPERTY_ORDER;
612
        }
613
614
        $short = EasyRdf\RdfNamespace::shorten($order);
615
        if ($short == 'skosmos:iso25964PropertyOrder') {
616
            return self::ISO25964_PROPERTY_ORDER;
617
        } elseif ($short == 'skosmos:defaultPropertyOrder') {
618
            return self::DEFAULT_PROPERTY_ORDER;
619
        }
620
        
621
        // check for custom order definition
622
        $orderList = $order->getResource('rdf:value');
623
        if ($orderList !== null && $orderList instanceof EasyRdf\Collection) {
624
            $ret = array();
625
            foreach ($orderList as $prop) {
626
                $short = $prop->shorten();
627
                $ret[] = ($short !== null) ? $short : $prop->getURI();
628
            }
629
            return $ret;
630
        }
631
        
632
        trigger_error("Property order for vocabulary '{$this->getShortName()}' unknown, using default order", E_USER_WARNING);
633
        return self::DEFAULT_PROPERTY_ORDER;
634
    }
635
}
636