Completed
Push — master ( 6eab88...4999fa )
by Henri
08:36
created

Concept::getXlLabel()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.2
c 0
b 0
f 0
cc 4
eloc 7
nc 3
nop 0
1
<?php
2
3
/**
4
 * Dataobject for a single concept.
5
 */
6
7
class Concept extends VocabularyDataObject
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
8
{
9
    /**
10
     * Stores a label string if the concept has been found through
11
     * a altLabel/label in a another language than the ui.
12
     */
13
    private $foundby;
14
    /** Type of foundby match: 'alt', 'hidden' or 'lang' */
15
    private $foundbytype;
16
    /** the EasyRdf\Graph object of the concept */
17
    private $graph;
18
    private $clang;
19
20
    /** concept properties that should not be shown to users */
21
    private $DELETED_PROPERTIES = array(
22
        'skosext:broaderGeneric', # these are remnants of bad modeling
23
        'skosext:broaderPartitive', #
24
25
        'skos:hiddenLabel', # because it's supposed to be hidden
26
        'skos:prefLabel', # handled separately by getLabel
27
        'rdfs:label', # handled separately by getLabel
28
29
        'skos:topConceptOf', # because it's too technical, not relevant for users
30
        'skos:inScheme', # should be evident in any case
31
        'skos:member', # this shouldn't be shown on the group page
32
        'dc:created', # handled separately
33
        'dc:modified', # handled separately
34
    );
35
36
    /** related concepts that should be shown to users in the appendix */
37
    private $MAPPING_PROPERTIES = array(
38
        'skos:exactMatch',
39
        'skos:narrowMatch',
40
        'skos:broadMatch',
41
        'skos:closeMatch',
42
        'skos:relatedMatch',
43
        'rdfs:seeAlso',
44
        'owl:sameAs',
45
    );
46
47
    /**
48
     * Initializing the concept object requires the following parameters.
49
     * @param Model $model
50
     * @param Vocabulary $vocab
51
     * @param EasyRdf\Resource $resource
52
     * @param EasyRdf\Graph $graph
53
     */
54
    public function __construct($model, $vocab, $resource, $graph, $clang)
55
    {
56
        parent::__construct($model, $vocab, $resource);
57
        $this->order = array("rdf:type", "dc:isReplacedBy", "skos:definition", "skos:broader", "skos:narrower", "skos:related", "skos:altLabel", "skosmos:memberOf", "skos:note", "skos:scopeNote", "skos:historyNote", "rdfs:comment", "dc11:source", "dc:source", "skos:prefLabel");
58
        $this->graph = $graph;
59
        $this->clang = $clang;
60
        // setting the Punic plugins locale for localized datetime conversions
61
        if ($this->clang && $this->clang !== '') {
62
            Punic\Data::setDefaultLocale($clang);
63
        }
64
65
    }
66
67
    /**
68
     * Returns the concept uri.
69
     * @return string
70
     */
71
    public function getUri()
72
    {
73
        return $this->resource->getUri();
74
    }
75
76
    public function getType()
77
    {
78
        return $this->resource->types();
79
    }
80
81
82
    /**
83
     * Returns a boolean value indicating whether the resource is a group defined in the vocab config as skosmos:groupClass.
84
     * @return boolean
85
     */
86
    public function isGroup() {
87
        $groupClass = $this->getVocab()->getConfig()->getGroupClassURI();
88
        if ($groupClass) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $groupClass 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...
89
            $groupClass = EasyRdf\RdfNamespace::shorten($groupClass) !== null ? EasyRdf\RdfNamespace::shorten($groupClass) : $groupClass;
90
            return in_array($groupClass, $this->getType());
91
        }
92
        return false;
93
    }
94
95
    /**
96
     * Returns a boolean value indicating if the concept has been deprecated.
97
     * @return boolean
98
     */
99
    public function getDeprecated()
100
    {
101
        $deprecatedValue = $this->resource->getLiteral('owl:deprecated');
102
        return ($deprecatedValue !== null && filter_var($deprecatedValue->getValue(), FILTER_VALIDATE_BOOLEAN));
103
    }
104
105
    /**
106
     * Returns a label for the concept in the content language or if not possible in any language.
107
     * @return string
108
     */
109
    public function getLabel()
110
    {
111 View Code Duplication
        foreach ($this->vocab->getConfig()->getLanguageOrder($this->clang) as $fallback) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
112
            if ($this->resource->label($fallback) !== null) {
113
                return $this->resource->label($fallback);
114
            }
115
            // We need to check all the labels in case one of them matches a subtag of the current language
116
            foreach($this->resource->allLiterals('skos:prefLabel') as $label) {
117
                // the label lang code is a subtag of the UI lang eg. en-GB - create a new literal with the main language
118
                if ($label !== null && strpos($label->getLang(), $fallback . '-') === 0) {
119
                    return EasyRdf\Literal::create($label, $fallback);
120
                }
121
            }
122
        }
123
124
        // Last resort: label in any language, including literal with empty language tag
125
        $label = $this->resource->label();
126
        if ($label !== null) {
127
            if (!$label->getLang()) {
128
                return $label->getValue();
129
            }
130
            return EasyRdf\Literal::create($label->getValue(), $label->getLang());
131
        }
132
133
        // empty
134
        return "";
135
    }
136
137
    public function hasXlLabel($prop = 'prefLabel')
138
    {
139
        if ($this->resource->hasProperty('skosxl:' . $prop)) {
140
            return true;
141
        }
142
        return false;
143
    }
144
145
    public function getXlLabel()
146
    {
147
        $labels = $this->resource->allResources('skosxl:prefLabel');
148
        foreach($labels as $labres) {
149
            $label = $labres->getLiteral('skosxl:literalForm');
150
            if ($label !== null && $label->getLang() == $this->clang) {
151
                return new LabelSkosXL($this->model, $labres);
152
            }
153
        }
154
        return null;
155
    }
156
157
    /**
158
     * Returns a notation for the concept or null if it has not been defined.
159
     * @return string eg. '999'
160
     */
161
    public function getNotation()
162
    {
163
        $notation = $this->resource->get('skos:notation');
164
        if ($this->vocab->getConfig()->showNotation() && $notation !== null) {
165
            return $notation->getValue();
166
        }
167
168
        return null;
169
    }
170
171
    /**
172
     * Returns the Vocabulary object or undefined if that is not available.
173
     * @return Vocabulary
174
     */
175
    public function getVocab()
176
    {
177
        return $this->vocab;
178
    }
179
180
    /**
181
     * Returns the vocabulary shortname string or id if that is not available.
182
     * @return string
183
     */
184
    public function getShortName()
185
    {
186
        return $this->vocab ? $this->vocab->getShortName() : null;
187
    }
188
189
    /**
190
     * Returns the vocabulary shortname string or id if that is not available.
191
     * @return string
192
     */
193
    public function getVocabTitle()
194
    {
195
        return $this->vocab ? $this->vocab->getTitle() : null;
196
    }
197
198
    /**
199
     * Setter for the $clang property.
200
     * @param string $clang language code eg. 'en'
201
     */
202
    public function setContentLang($clang)
203
    {
204
        $this->clang = $clang;
205
    }
206
207
    public function getContentLang()
208
    {
209
        return $this->clang;
210
    }
211
212
    /**
213
     * Setter for the $foundby property.
214
     * @param string $label label that was matched
215
     * @param string $type type of match: 'alt', 'hidden', or 'lang'
216
     */
217
    public function setFoundBy($label, $type)
218
    {
219
        $this->foundby = $label;
220
        $this->foundbytype = $type;
221
    }
222
223
    /**
224
     * Getter for the $foundby property.
225
     * @return string
226
     */
227
    public function getFoundBy()
228
    {
229
        return $this->foundby;
230
    }
231
232
    /**
233
     * Getter for the $foundbytype property.
234
     * @return string
235
     */
236
    public function getFoundByType()
237
    {
238
        return $this->foundbytype;
239
    }
240
241
    public function getMappingProperties()
242
    {
243
        $ret = array();
244
245
        $longUris = $this->resource->propertyUris();
246
        foreach ($longUris as &$prop) {
247 View Code Duplication
            if (EasyRdf\RdfNamespace::shorten($prop) !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
248
                // shortening property labels if possible
249
                $prop = $sprop = EasyRdf\RdfNamespace::shorten($prop);
250
            } else {
251
                $sprop = "<$prop>";
252
            }
253
            // EasyRdf requires full URIs to be in angle brackets
254
255
            if (in_array($prop, $this->MAPPING_PROPERTIES) && !in_array($prop, $this->DELETED_PROPERTIES)) {
256
                $propres = new EasyRdf\Resource($prop, $this->graph);
257
                $proplabel = $propres->label($this->getEnvLang()) ? $propres->label($this->getEnvLang()) : $propres->label(); // current language
258
                $propobj = new ConceptProperty($prop, $proplabel);
259
                if ($propobj->getLabel() !== null) {
260
                    // only display properties for which we have a label
261
                    $ret[$prop] = $propobj;
262
                }
263
264
                // Iterating through every resource and adding these to the data object.
265
                foreach ($this->resource->allResources($sprop) as $val) {
266
                    if (isset($ret[$prop])) {
267
                        // checking if the target vocabulary can be found at the skosmos endpoint
268
                        $exuri = $val->getUri();
269
                        // if multiple vocabularies are found, the following method will return in priority the current vocabulary of the concept
270
                        $exvoc = $this->model->guessVocabularyFromURI($exuri, $this->vocab->getId());
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $exvoc is correct as $this->model->guessVocab... $this->vocab->getId()) (which targets Model::guessVocabularyFromURI()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
271
                        // if not querying the uri itself
272
                        if (!$exvoc) {
273
                            $response = null;
274
                            // if told to do so in the vocabulary configuration
275
                            if ($this->vocab->getConfig()->getExternalResourcesLoading()) {
276
                                $response = $this->model->getResourceFromUri($exuri);
277
                            }
278
279
                            if ($response) {
280
                                $ret[$prop]->addValue(new ConceptMappingPropertyValue($this->model, $this->vocab, $response, $prop), $this->clang);
281
                                continue;
282
                            }
283
                        }
284
                        $ret[$prop]->addValue(new ConceptMappingPropertyValue($this->model, $this->vocab, $val, $prop, $this->clang), $this->clang);
285
                    }
286
                }
287
            }
288
        }
289
290
        // sorting the properties to a order preferred in the Skosmos concept page.
291
        $ret = $this->arbitrarySort($ret);
292
293
        return $ret;
294
    }
295
296
    /**
297
     * Iterates over all the properties of the concept and returns those in an array.
298
     * @return array
299
     */
300
    public function getProperties()
301
    {
302
        $properties = array();
303
        $narrowersByUri = array();
304
        $inCollection = array();
305
        $membersArray = array();
306
        $longUris = $this->resource->propertyUris();
307
        $duplicates = array();
308
        $ret = array();
309
310
        // looking for collections and linking those with their narrower concepts
311
        if ($this->vocab->getConfig()->getArrayClassURI() !== null) {
312
            $collections = $this->graph->allOfType($this->vocab->getConfig()->getArrayClassURI());
313
            if (sizeof($collections) > 0) {
314
                // indexing the narrowers once to avoid iterating all of them with every collection
315
                foreach ($this->resource->allResources('skos:narrower') as $narrower) {
316
                    $narrowersByUri[$narrower->getUri()] = $narrower;
317
                }
318
319
                foreach ($collections as $coll) {
320
                    $currCollMembers = $this->getCollectionMembers($coll, $narrowersByUri);
321
                    foreach ($currCollMembers as $collection) {
322
                        if ($collection->getSubMembers()) {
323
                            $submembers = $collection->getSubMembers();
324
                            foreach ($submembers as $member) {
325
                                $inCollection[$member->getUri()] = true;
326
                            }
327
328
                        }
329
                    }
330
331
                    if (isset($collection) && $collection->getSubMembers()) {
332
                        $membersArray = array_merge($currCollMembers, $membersArray);
333
                    }
334
335
                }
336
                $properties['skos:narrower'] = $membersArray;
337
            }
338
        }
339
340
        foreach ($longUris as &$prop) {
341
            // storing full URI without brackets in a separate variable
342
            $longUri = $prop;
343 View Code Duplication
            if (EasyRdf\RdfNamespace::shorten($prop) !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
344
                // shortening property labels if possible
345
                $prop = $sprop = EasyRdf\RdfNamespace::shorten($prop);
346
            } else {
347
                $sprop = "<$prop>";
348
            }
349
            // EasyRdf requires full URIs to be in angle brackets
350
351
            if (!in_array($prop, $this->DELETED_PROPERTIES) || ($this->isGroup() === false && $prop === 'skos:member')) {
352
                // retrieve property label and super properties from the current vocabulary first
353
                $propres = new EasyRdf\Resource($prop, $this->graph);
354
                $proplabel = $propres->label($this->getEnvLang()) ? $propres->label($this->getEnvLang()) : $propres->label();
355
356
                // if not found in current vocabulary, look up in the default graph to be able
357
                // to read an ontology loaded in a separate graph
358
                // note that this imply that the property has an rdf:type declared for the query to work
359
                if(!$proplabel) {
360
                    $envLangLabels = $this->model->getDefaultSparql()->queryLabel($longUri, $this->getEnvLang());
361
                    $proplabel = ($envLangLabels)?$envLangLabels[$this->getEnvLang()]:$this->model->getDefaultSparql()->queryLabel($longUri, '')[''];
362
                }
363
364
                // look for superproperties in the current graph
365
                $superprops = array();
366
                foreach ($this->graph->allResources($prop, 'rdfs:subPropertyOf') as $subi) {
367
                    $superprops[] = $subi->getUri();
368
                }
369
370
                // also look up superprops in the default graph if not found in current vocabulary
371
                if(!$superprops || empty($superprops)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $superprops of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
372
                    $superprops = $this->model->getDefaultSparql()->querySuperProperties($longUri);
373
                }
374
375
                // we're reading only one super property, even if there are multiple ones
376
                $superprop = ($superprops)?$superprops[0]:null;
377
                if ($superprop) {
378
                    $superprop = EasyRdf\RdfNamespace::shorten($superprop) ? EasyRdf\RdfNamespace::shorten($superprop) : $superprop;
379
                }
380
                $propobj = new ConceptProperty($prop, $proplabel, $superprop);
381
382
                if ($propobj->getLabel() !== null) {
383
                    // only display properties for which we have a label
384
                    $ret[$prop] = $propobj;
385
                }
386
387
                // searching for subproperties of literals too
388
                if($superprops) {
389
                    foreach ($superprops as $subi) {
390
                        $suburi = EasyRdf\RdfNamespace::shorten($subi) ? EasyRdf\RdfNamespace::shorten($subi) : $subi;
391
                        $duplicates[$suburi] = $prop;
392
                    }
393
                }
394
395
                // Iterating through every literal and adding these to the data object.
396
                foreach ($this->resource->allLiterals($sprop) as $val) {
397
                    $literal = new ConceptPropertyValueLiteral($this->model, $this->vocab, $this->resource, $val, $prop);
398
                    // only add literals when they match the content/hit language or have no language defined
399
                    if (isset($ret[$prop]) && ($literal->getLang() === $this->clang || $literal->getLang() === null)) {
400
                        $ret[$prop]->addValue($literal);
401
                    }
402
403
                }
404
405
                // Iterating through every resource and adding these to the data object.
406
                foreach ($this->resource->allResources($sprop) as $val) {
407
                    // skipping narrower concepts which are already shown in a collection
408
                    if ($sprop === 'skos:narrower' && array_key_exists($val->getUri(), $inCollection)) {
409
                        continue;
410
                    }
411
412
                    // hiding rdf:type property if it's just skos:Concept
413
                    if ($sprop === 'rdf:type' && $val->shorten() === 'skos:Concept') {
414
                        continue;
415
                    }
416
417
                    // handled by getMappingProperties()
418
                    if (in_array($sprop, $this->MAPPING_PROPERTIES)) {
419
                        continue;
420
                    }
421
422
                    if (isset($ret[$prop])) {
423
                        // checking if the property value is not in the current vocabulary
424
                        $exvoc = $this->model->guessVocabularyFromURI($val->getUri());
425
                        if ($exvoc && $exvoc->getId() !== $this->vocab->getId()) {
426
                            $ret[$prop]->addValue(new ConceptMappingPropertyValue($this->model, $this->vocab, $val, $prop, $this->clang), $this->clang);
427
                            continue;
428
                        }
429
                        $ret[$prop]->addValue(new ConceptPropertyValue($this->model, $this->vocab, $val, $prop, $this->clang), $this->clang);
430
                    }
431
432
                }
433
            }
434
        }
435
        // adding narrowers part of a collection
436
        foreach ($properties as $prop => $values) {
437
            foreach ($values as $value) {
438
                $ret[$prop]->addValue($value, $this->clang);
439
            }
440
        }
441
442
        foreach ($ret as $key => $prop) {
443
            if (sizeof($prop->getValues()) === 0) {
444
                unset($ret[$key]);
445
            }
446
        }
447
448
        $ret = $this->removeDuplicatePropertyValues($ret, $duplicates);
449
        // sorting the properties to the order preferred in the Skosmos concept page.
450
        $ret = $this->arbitrarySort($ret);
451
        return $ret;
452
    }
453
454
    /**
455
     * Removes properties that have duplicate values.
456
     * @param $ret the array of properties generated by getProperties
457
     * @param $duplicates array of properties found are a subProperty of a another property
458
     * @return array of ConceptProperties
459
     */
460
    public function removeDuplicatePropertyValues($ret, $duplicates)
461
    {
462
        $propertyValues = array();
463
464
        foreach ($ret as $prop) {
465
            foreach ($prop->getValues() as $value) {
466
                $label = $value->getLabel();
467
                $propertyValues[(method_exists($label, 'getValue')) ? $label->getValue() : $label][] = $value->getType();
468
            }
469
        }
470
471
        foreach ($propertyValues as $value => $propnames) {
472
            // if there are multiple properties with the same string value.
473
            if (count($propnames) > 1) {
474
                foreach ($propnames as $property) {
475
                    // if there is a more accurate property delete the more generic one.
476
                    if (isset($duplicates[$property])) {
477
                        unset($ret[$property]);
478
                    }
479
                }
480
481
            }
482
        }
483
        return $ret;
484
    }
485
486
    /**
487
     * Gets the creation date and modification date if available.
488
     * @return String containing the date information in a human readable format.
489
     */
490
    public function getDate()
491
    {
492
        $ret = '';
493
        $created = '';
494
        $modified = '';
495
        try {
496
            // finding the created properties
497
            if ($this->resource->get('dc:created')) {
498
                $created = $this->resource->get('dc:created')->getValue();
499
            }
500
501
            // finding the modified properties
502
            if ($this->resource->get('dc:modified')) {
503
                $modified = $this->resource->get('dc:modified')->getValue();
504
            }
505
506
            // making a human readable string from the timestamps
507
            if ($created != '') {
508
                $ret = gettext('skosmos:created') . ' ' . (Punic\Calendar::formatDate($created, 'short'));
509
            }
510
511
            if ($modified != '') {
512
                if ($created != '') {
513
                    $ret .= ', ' . gettext('skosmos:modified') . ' ' . (Punic\Calendar::formatDate($modified, 'short'));
514
                } else {
515
                    $ret .= ' ' . ucfirst(gettext('skosmos:modified')) . ' ' . (Punic\Calendar::formatDate($modified, 'short'));
516
                }
517
518
            }
519
        } catch (Exception $e) {
520
            trigger_error($e->getMessage(), E_USER_WARNING);
521
            $ret = '';
522
            if ($this->resource->get('dc:modified')) {
523
                $modified = (string) $this->resource->get('dc:modified');
524
                $ret = gettext('skosmos:modified') . ' ' . $modified;
525
            }
526
            if ($this->resource->get('dc:created')) {
527
                $created .= (string) $this->resource->get('dc:created');
528
                $ret .= ' ' . gettext('skosmos:created') . ' ' . $created;
529
            }
530
        }
531
        return $ret;
532
    }
533
534
    /**
535
     * Gets the members of a specific collection.
536
     * @param $coll
537
     * @param array containing all narrowers as EasyRdf\Resource
538
     * @return array containing ConceptPropertyValue objects
539
     */
540
    private function getCollectionMembers($coll, $narrowers)
541
    {
542
        $membersArray = array();
543
        $collLabel = $coll->label()->getValue($this->clang) ? $coll->label($this->clang) : $coll->label();
544
        if ($collLabel) {
545
            $collLabel = $collLabel->getValue();
546
        }
547
548
        $membersArray[$collLabel] = new ConceptPropertyValue($this->model, $this->vocab, $coll, 'skos:narrower', $this->clang);
549
        foreach ($coll->allResources('skos:member') as $member) {
550
            if (array_key_exists($member->getUri(), $narrowers)) {
551
                $narrower = $narrowers[$member->getUri()];
552
                if (isset($narrower)) {
553
                    $membersArray[$collLabel]->addSubMember(new ConceptPropertyValue($this->model, $this->vocab, $narrower, 'skos:member', $this->clang), $this->clang);
554
                }
555
556
            }
557
        }
558
559
        return $membersArray;
560
    }
561
562
    /**
563
     * Gets the groups the concept belongs to.
564
     */
565
    public function getGroupProperties()
566
    {
567
        return $this->getReverseResources(false);
568
    }
569
570
    /**
571
     * Gets the groups/arrays the concept belongs to.
572
     */
573
    public function getReverseResources($includeArrays) {
574
        $groups = array();
575
        $reverseResources = $this->graph->resourcesMatching('skos:member', $this->resource);
576
        if (isset($reverseResources)) {
577
            $arrayClassURI = $this->vocab !== null ? $this->vocab->getConfig()->getArrayClassURI() : null;
578
            $arrayClass = $arrayClassURI !== null ? EasyRdf\RdfNamespace::shorten($arrayClassURI) : null;
579
            $superGroups = $this->resource->all('isothes:superGroup');
580
            $superGroupUris = array_map(function($obj) { return $obj->getUri(); }, $superGroups);
581
            foreach ($reverseResources as $reverseResource) {
582
                if (in_array($arrayClass, $reverseResource->types()) === $includeArrays) {
0 ignored issues
show
Bug introduced by
The method types cannot be called on $reverseResource (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
583
                    // not adding the memberOf if the reverse resource is already covered by isothes:superGroup see issue #433
584
                    if (in_array($reverseResource->getUri(), $superGroupUris)) {
0 ignored issues
show
Bug introduced by
The method getUri cannot be called on $reverseResource (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
585
                        continue;
586
                    }
587
                    $property = in_array($arrayClass, $reverseResource->types()) ? "skosmos:memberOfArray" : "skosmos:memberOf";
0 ignored issues
show
Bug introduced by
The method types cannot be called on $reverseResource (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
588
                    $collLabel = $reverseResource->label($this->clang) ? $reverseResource->label($this->clang) : $reverseResource->label();
0 ignored issues
show
Bug introduced by
The method label cannot be called on $reverseResource (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
589
                    if ($collLabel) {
590
                        $collLabel = $collLabel->getValue();
591
                    }
592
593
                    $groups[$collLabel] = new ConceptPropertyValue($this->model, $this->vocab, $reverseResource, $property, $this->clang);
594
                    ksort($groups);
595
                    $super = $this->graph->resourcesMatching('skos:member', $reverseResource);
596
                    while (isset($super) && !empty($super)) {
597
                        foreach ($super as $res) {
598
                            $superprop = new ConceptPropertyValue($this->model, $this->vocab, $res, 'skosmos:memberOfSuper', $this->clang);
599
                            array_unshift($groups, $superprop);
600
                            $super = $this->graph->resourcesMatching('skos:member', $res);
601
                        }
602
                    }
603
                }
604
            }
605
        }
606
        return $groups;
607
    }
608
609
    public function getArrayProperties() {
610
        return $this->getReverseResources(true);
611
    }
612
613
    /**
614
     * Reads the literal language code and gets a name for it from Punic or alternatively
615
     * tries to search for a gettext translation.
616
     * @param EasyRdf\Literal $lit
617
     * @return string e.g. 'English'
618
     */
619
    private function literalLanguageToString($lit) {
620
        // using empty string as the language literal when there is no langcode set
621
        $langName = '';
622
        if ($lit->getLang() !== null) {
623
            $langName = Punic\Language::getName($lit->getLang(), $this->getEnvLang()) !== $lit->getLang() ? Punic\Language::getName($lit->getLang(), $this->getEnvLang()) : gettext($lit->getLang());
624
        }
625
        return $langName;
626
    }
627
628
    /**
629
     * Gets the values for the property in question in all other languages than the ui language.
630
     */
631
    public function getForeignLabels()
632
    {
633
        $prefLabels = $this->resource->allLiterals('skos:prefLabel');
634
        $labels = array_merge($prefLabels, $this->resource->allLiterals('skos:altLabel'));
635
        $ret = array();
636
        foreach ($labels as $lit) {
637
            // filtering away subsets of the current language eg. en vs en-GB
638
            if ($lit->getLang() != $this->clang && strpos($lit->getLang(), $this->getEnvLang() . '-') !== 0) {
639
                $prop = in_array($lit, $prefLabels) ? 'skos:prefLabel' : 'skos:altLabel';
640
                $ret[$this->literalLanguageToString($lit)][] = new ConceptPropertyValueLiteral($this->model, $this->vocab, $this->resource, $lit, $prop);
641
            }
642
        }
643
        ksort($ret);
644
        return $ret;
645
    }
646
647
    /**
648
     * Gets the values for the property in question in all other languages than the ui language.
649
     * @param string $property
650
     */
651
    public function getAllLabels($property)
652
    {
653
        $labels = array();
654
        // shortening property labels if possible, EasyRdf requires full URIs to be in angle brackets
655
        $property = (EasyRdf\RdfNamespace::shorten($property) !== null) ? EasyRdf\RdfNamespace::shorten($property) : "<$property>";
656
        foreach ($this->resource->allLiterals($property) as $lit) {
657
            $labels[Punic\Language::getName($lit->getLang(), $this->getEnvLang())][] = new ConceptPropertyValueLiteral($this->model, $this->vocab, $this->resource, $lit, $property);
658
        }
659
        ksort($labels);
660
        return $labels;
661
    }
662
}
663