Completed
Push — master ( 9de5b8...ac5bab )
by Osma
02:11
created

Vocabulary::getShortName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Vocabulary dataobjects provide access to the vocabularies on the SPARQL endpoint.
5
 */
6
class Vocabulary extends DataObject
7
{
8
    /** cached value of URI space */
9
    private $urispace = null;
10
    private $config;
11
12
    public function __construct($model, $resource)
13
    {
14
        parent::__construct($model, $resource);
15
        $this->config = new VocabularyConfig($resource, $model->getConfig()->getGlobalPlugins());
16
    }
17
18
    /**
19
     * Returns the VocabularyConfig object
20
     * @return VocabularyConfig
21
     */
22
    public function getConfig()
23
    {
24
      return $this->config;
25
    }
26
27
    /**
28
     * Get the SPARQL endpoint URL for this vocabulary
29
     *
30
     * @return string endpoint URL
31
     */
32
    public function getEndpoint()
33
    {
34
        return $this->resource->get('void:sparqlEndpoint')->getUri();
35
    }
36
37
    /**
38
     * Get the SPARQL graph URI for this vocabulary
39
     *
40
     * @return string graph URI
41
     */
42
    public function getGraph()
43
    {
44
        $graph = $this->resource->get('skosmos:sparqlGraph');
45
        if ($graph) {
46
            $graph = $graph->getUri();
47
        }
48
49
        return $graph;
50
    }
51
52
    /**
53
     * Get the SPARQL implementation for this vocabulary
54
     *
55
     * @return GenericSparql SPARQL object
56
     */
57
    public function getSparql()
58
    {
59
        $endpoint = $this->getEndpoint();
60
        $graph = $this->getGraph();
61
        $dialect = $this->resource->get('skosmos:sparqlDialect');
62
        $dialect = $dialect ? $dialect->getValue() : $this->model->getConfig()->getDefaultSparqlDialect();
63
64
        return $this->model->getSparqlImplementation($dialect, $endpoint, $graph);
65
    }
66
67
    /**
68
     * Get the URI space of concepts in this vocabulary.
69
     *
70
     * @return string full URI of concept
71
     */
72
    public function getUriSpace()
73
    {
74
        if ($this->urispace === null) // initialize cache
75
        {
76
            $this->urispace = $this->resource->getLiteral('void:uriSpace')->getValue();
77
        }
78
79
        return $this->urispace;
80
    }
81
82
    /**
83
     * Get the full URI of a concept in a vocabulary. If the passed local
84
     * name is already a full URI, return it unchanged.
85
     *
86
     * @param $lname string local name of concept
87
     * @return string full URI of concept
88
     */
89
    public function getConceptURI($lname)
90
    {
91
        if (strpos($lname, 'http') === 0) {
92
            return $lname;
93
        }
94
        // already a full URI
95
        return $this->getUriSpace() . $lname;
96
    }
97
98
    /**
99
     * Asks the sparql implementation to make a label query for a uri.
100
     * @param string $uri
101
     * @param string $lang
102
     */
103
    public function getConceptLabel($uri, $lang)
104
    {
105
        return $this->getSparql()->queryLabel($uri, $lang);
106
    }
107
108
    /**
109
     * Get the localname of a concept in the vocabulary. If the URI is not
110
     * in the URI space of this vocabulary, return the full URI.
111
     *
112
     * @param $uri string full URI of concept
113
     * @return string local name of concept, or original full URI if the local name cannot be determined
114
     */
115
    public function getLocalName($uri)
116
    {
117
        return str_replace($this->getUriSpace(), "", $uri);
118
    }
119
120
    /**
121
     * Retrieves all the information about the Vocabulary
122
     * from the SPARQL-endpoint.
123
     */
124
    public function getInfo($lang = null)
125
    {
126
        $ret = array();
127
        if (!$lang) {
128
            $lang = $this->getEnvLang();
129
        }
130
131
        // get metadata (literals only e.g. name) from vocabulary configuration file
132
        foreach ($this->resource->properties() as $prop) {
133
            foreach ($this->resource->allLiterals($prop, $lang) as $val) {
134
                $ret[$prop][] = $val->getValue();
135
            }
136
        }
137
138
        // also include ConceptScheme metadata from SPARQL endpoint
139
        $defaultcs = $this->getDefaultConceptScheme();
140
141
        // query everything the endpoint knows about the ConceptScheme
142
        $sparql = $this->getSparql();
143
        $result = $sparql->queryConceptScheme($defaultcs);
144
        $conceptscheme = $result->resource($defaultcs);
0 ignored issues
show
Bug introduced by
The method resource does only exist in EasyRdf\Graph, but not in EasyRdf\Http\Response and EasyRdf\Sparql\Result.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
145
        $this->order = array("dc:title", "dc11:title", "skos:prefLabel", "rdfs:label", "dc:subject", "dc11:subject", "dc:description", "dc11:description", "dc:publisher", "dc11:publisher", "dc:creator", "dc11:creator", "dc:contributor", "dc:language", "dc11:language", "owl:versionInfo", "dc:source", "dc11:source");
146
147
        foreach ($conceptscheme->properties() as $prop) {
148
            foreach ($conceptscheme->allLiterals($prop, $lang) as $val) {
149
                $prop = (substr($prop, 0, 5) == 'dc11:') ? str_replace('dc11:', 'dc:', $prop) : $prop;
150
                $ret[$prop][$val->getValue()] = $val;
151
            }
152
            if (!isset($ret[$prop]) || sizeof($ret[$prop]) == 0) { // not found with language tag
153
                foreach ($conceptscheme->allLiterals($prop, null) as $val) {
154
                    $prop = (substr($prop, 0, 5) == 'dc11:') ? str_replace('dc11:', 'dc:', $prop) : $prop;
155
                    if ($val->getValue() instanceof DateTime) {
156
                        $val = Punic\Calendar::formatDate($val->getValue(), 'full', $lang) . ' ' . Punic\Calendar::format($val->getValue(), 'HH:mm:ss', $lang);
157
                    }
158
                    $ret[$prop][] = $val;
159
                }
160
            }
161
            foreach ($conceptscheme->allResources($prop) as $val) {
162
                $prop = (substr($prop, 0, 5) == 'dc11:') ? str_replace('dc11:', 'dc:', $prop) : $prop;
163
                $exvocab = $this->model->guessVocabularyFromURI($val->getURI());
164
                $exlabel = $this->getExternalLabel($exvocab, $val->getURI(), $lang);
0 ignored issues
show
Bug introduced by
It seems like $exvocab defined by $this->model->guessVocab...FromURI($val->getURI()) on line 163 can be null; however, DataObject::getExternalLabel() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
165
                if (isset($exlabel)) {
166
                    $val->add('skosmos:vocab', $exvocab->getId());
167
                    $val->add('skosmos:label', $exlabel);
168
                }
169
                $label = $val->label($lang) ? $val->label($lang)->getValue() : $val->getUri();
170
                $ret[$prop][$exlabel ? $exlabel->getValue() : $label] = $val;
171
            }
172
            if (isset($ret[$prop])) {
173
                ksort($ret[$prop]);
174
            }
175
        }
176
        if (isset($ret['owl:versionInfo'])) { // if version info availible for vocabulary convert it to a more readable format
177
            $ret['owl:versionInfo'][0] = $this->parseVersionInfo($ret['owl:versionInfo'][0]);
178
        }
179
        // remove duplicate values
180
        foreach (array_keys($ret) as $prop) {
181
            $ret[$prop] = array_unique($ret[$prop]);
182
        }
183
184
        $ret = $this->arbitrarySort($ret);
185
186
        // filtering multiple labels
187
        if (isset($ret['dc:title'])) {
188
            unset($ret['dc11:title'], $ret['skos:prefLabel'], $ret['rdfs:label']);
189
        } else if (isset($ret['dc11:title'])) {
190
            unset($ret['skos:prefLabel'], $ret['rdfs:label']);
191
        } else if (isset($ret['skos:prefLabel'])) {
192
            unset($ret['rdfs:label']);
193
        }
194
195
        return $ret;
196
    }
197
198
    /**
199
     * Return all concept schemes in the vocabulary.
200
     * @return array Array with concept scheme URIs (string) as keys and labels (string) as values
201
     */
202
203
    public function getConceptSchemes($lang = '')
204
    {
205
        if ($lang === '') {
206
            $lang = $this->getEnvLang();
207
        }
208
209
        return $this->getSparql()->queryConceptSchemes($lang);
210
    }
211
212
    /**
213
     * Return the URI of the default concept scheme of this vocabulary. If the skosmos:mainConceptScheme property is set in the
214
     * vocabulary configuration, that will be returned. Otherwise an arbitrary concept scheme will be returned.
215
     * @return string concept scheme URI
216
     */
217
218
    public function getDefaultConceptScheme()
219
    {
220
        $conceptScheme = $this->config->getMainConceptSchemeURI();
221
        if ($conceptScheme) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $conceptScheme 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...
222
            return $conceptScheme;
223
        }
224
225
        // mainConceptScheme not explicitly set, guess it
226
        $conceptSchemes = $this->getConceptSchemes();
227
        $conceptSchemeURIs = array_keys($conceptSchemes);
228
        // return the URI of the last concept scheme
229
        return array_pop($conceptSchemeURIs);
230
    }
231
232
    /**
233
     * Returns the main Concept Scheme of that Vocabulary, or null if not set.
234
     * @param string $defaultConceptSchemeURI default concept scheme URI
235
     * @return \EasyRdf\Graph|mixed
236
     */
237
    public function getConceptScheme(string $defaultConceptSchemeURI)
238
    {
239
        return $this->getSparql()->queryConceptScheme($defaultConceptSchemeURI);
240
    }
241
242
    /**
243
     * Return the top concepts of a concept scheme in the vocabulary.
244
     * @param string $conceptScheme URI of concept scheme whose top concepts to return. If not set,
245
     *                              the default concept scheme of the vocabulary will be used.
246
     * @param string $lang preferred language for the concept labels,
247
     * @return array Array with concept URIs (string) as keys and labels (string) as values
248
     */
249
250
    public function getTopConcepts($conceptScheme = null, $lang = '')
251
    {
252
        if ($lang === '') {
253
            $lang = $this->getEnvLang();
254
        }
255
        $fallback = $this->config->getDefaultLanguage();
256
257
        if ($conceptScheme === null || $conceptScheme == '') {
258
            $conceptScheme = $this->getDefaultConceptScheme();
259
        }
260
261
        return $this->getSparql()->queryTopConcepts($conceptScheme, $lang, $fallback);
262
    }
263
264
    /**
265
     * Tries to parse version, date and time from sparql version information into a readable format.
266
     * @param string $version
267
     * @return string
268
     */
269
    private function parseVersionInfo($version)
270
    {
271
        $parts = explode(' ', $version);
272
        if ($parts[0] != '$Id:') {
273
            return $version;
274
        }
275
        // don't know how to parse
276
        $rev = $parts[2];
277
        $datestr = $parts[3] . ' ' . $parts[4];
278
279
        return "$datestr (r$rev)";
280
    }
281
282
    /**
283
     * Counts the statistics of the vocabulary.
284
     * @return array of the concept/group counts
285
     */
286
    public function getStatistics($lang = '', $array=null, $group=null)
287
    {
288
        $sparql = $this->getSparql();
289
        // find the number of concepts
290
        return $sparql->countConcepts($lang, $array, $group);
291
    }
292
293
    /**
294
     * Counts the statistics of the vocabulary.
295
     * @return array of the concept counts in different languages
296
     */
297
    public function getLabelStatistics()
298
    {
299
        $sparql = $this->getSparql();
300
        $ret = array();
301
        // count the number of different types of concepts in all languages
302
        $ret['terms'] = $sparql->countLangConcepts($this->config->getLanguages(), $this->config->getIndexClasses());
303
304
        return $ret;
305
    }
306
307
    /**
308
     * Gets the parent concepts of a concept and child concepts for all of those.
309
     * @param string $uri
310
     * @param string $lang language identifier.
311
     */
312 View Code Duplication
    public function getConceptHierarchy($uri, $lang)
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...
313
    {
314
        $lang = $lang ? $lang : $this->getEnvLang();
315
        $fallback = count($this->config->getLanguageOrder($lang)) > 1 ? $this->config->getLanguageOrder($lang)[1] : $this->config->getDefaultLanguage();
316
        $props = $this->config->getHierarchyProperty();
317
        return $this->getSparql()->queryParentList($uri, $lang, $fallback, $props);
318
    }
319
320
    /**
321
     * Gets the child relations of a concept and whether these children have more children.
322
     * @param string $uri
323
     */
324 View Code Duplication
    public function getConceptChildren($uri, $lang)
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...
325
    {
326
        $lang = $lang ? $lang : $this->getEnvLang();
327
        $fallback = count($this->config->getLanguageOrder($lang)) > 1 ? $this->config->getLanguageOrder($lang)[1] : $this->config->getDefaultLanguage();
328
        $props = $this->config->getHierarchyProperty();
329
        return $this->getSparql()->queryChildren($uri, $lang, $fallback, $props);
330
    }
331
332
    /**
333
     * Gets the skos:narrower relations of a concept.
334
     * @param string $uri
335
     * @param string $lang language identifier.
336
     */
337
    public function getConceptNarrowers($uri, $lang)
338
    {
339
        $lang = $lang ? $lang : $this->getEnvLang();
340
        return $this->getSparql()->queryProperty($uri, 'skos:narrower', $lang);
341
    }
342
343
    /**
344
     * Gets the skos:narrowerTransitive relations of a concept.
345
     * @param string $uri
346
     * @param integer $limit
347
     * @param string $lang language identifier.
348
     */
349
    public function getConceptTransitiveNarrowers($uri, $limit, $lang)
350
    {
351
        $lang = $lang ? $lang : $this->getEnvLang();
352
        return $this->getSparql()->queryTransitiveProperty($uri, array('skos:narrower'), $lang, $limit);
353
    }
354
355
    /**
356
     * Gets the skos:broader relations of a concept.
357
     * @param string $uri
358
     * @param string $lang language identifier.
359
     */
360
    public function getConceptBroaders($uri, $lang)
361
    {
362
        $lang = $lang ? $lang : $this->getEnvLang();
363
        return $this->getSparql()->queryProperty($uri, 'skos:broader', $lang);
364
    }
365
366
    /**
367
     * Gets the skos:broaderTransitive relations of a concept.
368
     * @param string $uri
369
     * @param integer $limit
370
     * @param boolean $any set to true if you want to have a label even in case of a correct language one missing.
371
     * @param string $lang language identifier.
372
     */
373
    public function getConceptTransitiveBroaders($uri, $limit, $any = false, $lang)
374
    {
375
        $lang = $lang ? $lang : $this->getEnvLang();
376
        $fallback = $this->config->getDefaultLanguage();
377
        return $this->getSparql()->queryTransitiveProperty($uri, array('skos:broader'), $lang, $limit, $any, $fallback);
378
    }
379
380
    /**
381
     * Gets all the skos:related concepts of a concept.
382
     * @param string $uri
383
     * @param string $lang language identifier.
384
     */
385
    public function getConceptRelateds($uri, $lang)
386
    {
387
        $lang = $lang ? $lang : $this->getEnvLang();
388
        return $this->getSparql()->queryProperty($uri, 'skos:related', $lang);
389
    }
390
391
    /**
392
     * Makes a query into the sparql endpoint for a concept.
393
     * @param string $uri the full URI of the concept
394
     * @return Concept[]
395
     */
396
    public function getConceptInfo($uri, $clang)
397
    {
398
        $sparql = $this->getSparql();
399
400
        return $sparql->queryConceptInfo($uri, $this->config->getArrayClassURI(), array($this), $clang);
401
    }
402
403
    /**
404
     * Lists the different concept groups available in the vocabulary.
405
     * @param string $clang content language parameter
406
     * @return array
407
     */
408
    public function listConceptGroups($clang = null)
409
    {
410
        if ($clang === null || $clang == '') {
411
            $clang = $this->getEnvLang();
412
        }
413
414
        $ret = array();
415
        $gclass = $this->config->getGroupClassURI();
416
        if ($gclass === null) {
417
            return $ret;
418
        }
419
        // no group class defined, so empty result
420
        $groups = $this->getSparql()->listConceptGroups($gclass, $clang);
421
        foreach ($groups as $uri => $label) {
422
            $ret[$uri] = $label;
423
        }
424
425
        return $ret;
426
    }
427
428
    /**
429
     * Lists the concepts available in the concept group.
430
     * @param $clname
431
     * @return array
432
     */
433
    public function listConceptGroupContents($glname, $clang)
434
    {
435
        if (!$clang) {
436
            $clang = $this->config->getEnvLang();
437
        }
438
439
        $ret = array();
440
        $gclass = $this->config->getGroupClassURI();
441
        if ($gclass === null) {
442
            return $ret;
443
        }
444
        // no group class defined, so empty result
445
        $group = $this->getConceptURI($glname);
446
        $contents = $this->getSparql()->listConceptGroupContents($gclass, $group, $clang, $this->config->getShowDeprecated());
447
        foreach ($contents as $uri => $label) {
448
            $ret[$uri] = $label;
449
        }
450
451
        return $ret;
452
    }
453
454
    /**
455
     * Returns the letters of the alphabet which have been used in this vocabulary.
456
     * The returned letters may also include specials such as '0-9' (digits) and '!*' (special characters).
457
     * @param $clang content language
458
     * @return array array of letters
459
     */
460
    public function getAlphabet($clang)
461
    {
462
        $chars = $this->getSparql()->queryFirstCharacters($clang, $this->config->getIndexClasses());
463
        $letters = array();
464
        $digits = false;
465
        $specials = false;
466
        foreach ($chars as $char) {
467
            if (preg_match('/\p{L}/u', $char)) {
468
                $letters[] = $char;
469
            } elseif (preg_match('/\d/u', $char)) {
470
                $digits = true;
471
            } else {
472
                $specials = true;
473
            }
474
        }
475
        usort($letters, 'strcoll');
476
        if ($specials) {
477
            $letters[] = '!*';
478
        }
479
480
        if ($digits) {
481
            $letters[] = '0-9';
482
        }
483
484
        return $letters;
485
    }
486
487
    /**
488
     * Searches for concepts with a label starting with the specified letter.
489
     * Also the special tokens '0-9' (digits), '!*' (special characters) and '*'
490
     * (everything) are supported.
491
     * @param $letter letter (or special token) to search for
492
     */
493
    public function searchConceptsAlphabetical($letter, $limit = null, $offset = null, $clang = null)
494
    {
495
        return $this->getSparql()->queryConceptsAlphabetical($letter, $clang, $limit, $offset, $this->config->getIndexClasses(),$this->config->getShowDeprecated());
496
    }
497
498
    /**
499
     * Makes a query for the transitive broaders of a concept and returns the concepts hierarchy processed for the view.
500
     * @param string $lang
501
     * @param string $uri
502
     */
503
    public function getBreadCrumbs($lang, $uri)
504
    {
505
        $broaders = $this->getConceptTransitiveBroaders($uri, 1000, true, $lang);
506
        $origCrumbs = $this->getCrumbs($broaders, $uri);
0 ignored issues
show
Bug introduced by
It seems like $broaders defined by $this->getConceptTransit...uri, 1000, true, $lang) on line 505 can also be of type null; however, Vocabulary::getCrumbs() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
507
        return $this->combineCrumbs($origCrumbs);
508
    }
509
510
    /**
511
     * Takes the crumbs as a parameter and combines the crumbs if the path they form is too long.
512
     * @return array
513
     */
514
    private function combineCrumbs($origCrumbs)
515
    {
516
        $combined = array();
517
        foreach ($origCrumbs as $pathKey => $path) {
518
            $firstToCombine = true;
519
            $combinedPath = array();
520
            foreach ($path as $crumbKey => $crumb) {
521
                if ($crumb->getPrefLabel() === '...') {
522
                    array_push($combinedPath, $crumb);
523
                    if ($firstToCombine) {
524
                        $firstToCombine = false;
525
                    } else {
526
                        unset($origCrumbs[$pathKey][$crumbKey]);
527
                    }
528
                }
529
            }
530
            $combined[] = $combinedPath;
531
        }
532
533
        return array('combined' => $combined, 'breadcrumbs' => $origCrumbs);
534
    }
535
536
    /**
537
     * Recursive function for building the breadcrumb paths for the view.
538
     * @param array $bTresult contains the results of the broaderTransitive query.
539
     * @param string $uri
540
     * @param array $path
541
     */
542
    private function getCrumbs($bTresult, $uri, $path = null)
543
    {
544
        $crumbs = array();
545
        if (!isset($path)) {
546
            $path = array();
547
        }
548
549
        // check that there is no cycle (issue #220)
550
        foreach ($path as $childcrumb) {
551
            if ($childcrumb->getUri() == $uri) {
552
                // found a cycle - short-circuit and stop
553
                return $crumbs;
554
            }
555
        }
556
        if (isset($bTresult[$uri]['direct'])) {
557
            foreach ($bTresult[$uri]['direct'] as $broaderUri) {
558
                $newpath = array_merge($path, array(new Breadcrumb($uri, $bTresult[$uri]['label'])));
559
                if ($uri !== $broaderUri) {
560
                    $crumbs = array_merge($crumbs, $this->getCrumbs($bTresult, $broaderUri, $newpath));
561
                }
562
            }
563
        } else { // we have reached the end of a path and we need to start a new row in the 'stack'
564
            if (isset($bTresult[$uri])) {
565
                $path = array_merge($path, array(new Breadcrumb($uri, $bTresult[$uri]['label'])));
566
            }
567
568
            $index = 1;
569
            $length = sizeof($path);
570
            $limit = $length - 5;
571
            foreach ($path as $crumb) {
572
                if ($length > 5 && $index > $length - $limit) { // displays 5 concepts closest to the concept.
573
                    $crumb->hideLabel();
574
                }
575
                $index++;
576
            }
577
            $crumbs[] = array_reverse($path);
578
        }
579
        return $crumbs;
580
    }
581
582
    /**
583
     * Verify that the requested language is supported by the vocabulary. If not, returns
584
     * the default language of the vocabulary.
585
     * @param string $lang language to check
586
     * @return string language tag that is supported by the vocabulary
587
     */
588
589
    public function verifyVocabularyLanguage($lang)
590
    {
591
        return (in_array($lang, $this->config->getLanguages())) ? $lang : $this->config->getDefaultLanguage();
592
    }
593
594
    /**
595
     * Returns a list of recently changed or entirely new concepts.
596
     * @param string $clang content language for the labels
597
     * @param string $lang UI language for the dates
598
     * @return Array
599
     */
600
    public function getChangeList($prop, $clang, $lang, $offset)
601
    {
602
      $changelist = $this->getSparql()->queryChangeList($clang, $offset, $prop);
603
      $bydate = array();
604
      foreach($changelist as $concept) {
605
        $concept['datestring'] = Punic\Calendar::formatDate($concept['date'], 'medium', $lang);
606
        $bydate[Punic\Calendar::getMonthName($concept['date'], 'wide', $lang, true) . Punic\Calendar::format($concept['date'], ' y', $lang) ][strtolower($concept['prefLabel'])] = $concept;
607
      }
608
      return $bydate;
609
    }
610
611
    public function getTitle($lang=null) {
612
      return $this->config->getTitle($lang);
613
    }
614
615
    public function getShortName() {
616
      return $this->config->getShortName();
617
    }
618
619
    public function getId() {
620
      return $this->config->getId();
621
    }
622
623
}
624