Passed
Branch master (4b538d)
by Osma
10:57
created

RestController::labelStatistics()   B

Complexity

Conditions 6
Paths 11

Size

Total Lines 50
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 35
nc 11
nop 1
dl 0
loc 50
rs 8.7377
c 2
b 0
f 0
1
<?php
2
3
/**
4
 * RestController is responsible for handling all the requests directed to the /rest address.
5
 */
6
class RestController extends Controller
7
{
8
    /* supported MIME types that can be used to return RDF data */
9
    const SUPPORTED_FORMATS = 'application/rdf+xml text/turtle application/ld+json application/json application/marcxml+xml';
10
    /* context array template */
11
    private $context = array(
12
        '@context' => array(
13
            'skos' => 'http://www.w3.org/2004/02/skos/core#',
14
            'uri' => '@id',
15
            'type' => '@type',
16
        ),
17
    );
18
19
    /**
20
     * Handles json encoding, adding the content type headers and optional callback function.
21
     * @param array $data the data to be returned.
22
     */
23
    private function returnJson($data)
24
    {
25
        // wrap with JSONP callback if requested
26
        if (filter_input(INPUT_GET, 'callback', FILTER_SANITIZE_STRING)) {
27
            header("Content-type: application/javascript; charset=utf-8");
28
            echo filter_input(INPUT_GET, 'callback', FILTER_UNSAFE_RAW) . "(" . json_encode($data) . ");";
29
            return;
30
        }
31
32
        // otherwise negotiate suitable format for the response and return that
33
        $negotiator = new \Negotiation\Negotiator();
0 ignored issues
show
Bug introduced by
The type Negotiation\Negotiator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
34
        $priorities = array('application/json', 'application/ld+json');
35
        $best = filter_input(INPUT_SERVER, 'HTTP_ACCEPT', FILTER_SANITIZE_STRING) ? $negotiator->getBest(filter_input(INPUT_SERVER, 'HTTP_ACCEPT', FILTER_SANITIZE_STRING), $priorities) : null;
36
        $format = ($best !== null) ? $best->getValue() : $priorities[0];
37
        header("Content-type: $format; charset=utf-8");
38
        header("Vary: Accept"); // inform caches that we made a choice based on Accept header
39
        echo json_encode($data);
40
    }
41
42
    /**
43
     * Parses and returns the limit parameter. Returns and error if the parameter is missing.
44
     */
45
    private function parseLimit()
46
    {
47
        $limit = filter_input(INPUT_GET, 'limit', FILTER_SANITIZE_NUMBER_INT) ? filter_input(INPUT_GET, 'limit', FILTER_SANITIZE_NUMBER_INT) : $this->model->getConfig()->getDefaultTransitiveLimit();
48
        if ($limit <= 0) {
49
            return $this->returnError(400, "Bad Request", "Invalid limit parameter");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(400, ...valid limit parameter') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
50
        }
51
52
        return $limit;
53
    }
54
55
56
/** Global REST methods **/
57
58
    /**
59
     * Returns all the vocabularies available on the server in a json object.
60
     */
61
    public function vocabularies($request)
62
    {
63
        if (!$request->getLang()) {
64
            return $this->returnError(400, "Bad Request", "lang parameter missing");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(400, ...ang parameter missing') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
65
        }
66
67
        $this->setLanguageProperties($request->getLang());
68
69
        $vocabs = array();
70
        foreach ($this->model->getVocabularies() as $voc) {
71
            $vocabs[$voc->getId()] = $voc->getConfig()->getTitle($request->getLang());
72
        }
73
        ksort($vocabs);
74
        $results = array();
75
        foreach ($vocabs as $id => $title) {
76
            $results[] = array(
77
                'uri' => $id,
78
                'id' => $id,
79
                'title' => $title);
80
        }
81
82
        /* encode the results in a JSON-LD compatible array */
83
        $ret = array(
84
            '@context' => array(
85
                'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
86
                'onki' => 'http://schema.onki.fi/onki#',
87
                'title' => array('@id' => 'rdfs:label', '@language' => $request->getLang()),
88
                'vocabularies' => 'onki:hasVocabulary',
89
                'id' => 'onki:vocabularyIdentifier',
90
                'uri' => '@id',
91
                '@base' => $this->getBaseHref() . "rest/v1/vocabularies",
92
            ),
93
            'uri' => '',
94
            'vocabularies' => $results,
95
        );
96
97
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
98
    }
99
100
    private function constructSearchParameters($request)
101
    {
102
        $parameters = new ConceptSearchParameters($request, $this->model->getConfig(), true);
103
104
        $vocabs = $request->getQueryParam('vocab'); # optional
105
        // convert to vocids array to support multi-vocabulary search
106
        $vocids = ($vocabs !== null && $vocabs !== '') ? explode(' ', $vocabs) : array();
107
        $vocabObjects = array();
108
        foreach($vocids as $vocid) {
109
            $vocabObjects[] = $this->model->getVocabulary($vocid);
110
        }
111
        $parameters->setVocabularies($vocabObjects);
112
        return $parameters;
113
    }
114
115
    private function transformSearchResults($request, $results, $parameters)
116
    {
117
        // before serializing to JSON, get rid of the Vocabulary object that came with each resource
118
        foreach ($results as &$res) {
119
            unset($res['voc']);
120
        }
121
122
        $context = array(
123
            'skos' => 'http://www.w3.org/2004/02/skos/core#',
124
            'isothes' => 'http://purl.org/iso25964/skos-thes#',
125
            'onki' => 'http://schema.onki.fi/onki#',
126
            'uri' => '@id',
127
            'type' => '@type',
128
            'results' => array(
129
                '@id' => 'onki:results',
130
                '@container' => '@list',
131
            ),
132
            'prefLabel' => 'skos:prefLabel',
133
            'altLabel' => 'skos:altLabel',
134
            'hiddenLabel' => 'skos:hiddenLabel',
135
        );
136
        foreach ($parameters->getAdditionalFields() as $field) {
137
138
            // Quick-and-dirty compactification
139
            $context[$field] = 'skos:' . $field;
140
            foreach ($results as &$result) {
141
                foreach ($result as $k => $v) {
142
                    if ($k == 'skos:' . $field) {
143
                        $result[$field] = $v;
144
                        unset($result['skos:' . $field]);
145
                    }
146
                }
147
            }
148
        }
149
150
        $ret = array(
151
            '@context' => $context,
152
            'uri' => '',
153
            'results' => $results,
154
        );
155
156
        if (isset($results[0]['prefLabels'])) {
157
            $ret['@context']['prefLabels'] = array('@id' => 'skos:prefLabel', '@container' => '@language');
158
        }
159
160
        if ($request->getQueryParam('labellang')) {
161
            $ret['@context']['@language'] = $request->getQueryParam('labellang');
162
        } elseif ($request->getQueryParam('lang')) {
163
            $ret['@context']['@language'] = $request->getQueryParam('lang');
164
        }
165
        return $ret;
166
    }
167
168
    /**
169
     * Performs the search function calls. And wraps the result in a json-ld object.
170
     * @param Request $request
171
     */
172
    public function search($request)
173
    {
174
        $maxhits = $request->getQueryParam('maxhits');
175
        $offset = $request->getQueryParam('offset');
176
        $term = $request->getQueryParamRaw('query');
177
178
        if (!$term && (!$request->getQueryParam('group') && !$request->getQueryParam('parent'))) {
179
            return $this->returnError(400, "Bad Request", "query parameter missing");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(400, ...ery parameter missing') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
180
        }
181
        if ($maxhits && (!is_numeric($maxhits) || $maxhits <= 0)) {
182
            return $this->returnError(400, "Bad Request", "maxhits parameter is invalid");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(400, ... parameter is invalid') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
183
        }
184
        if ($offset && (!is_numeric($offset) || $offset < 0)) {
185
            return $this->returnError(400, "Bad Request", "offset parameter is invalid");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(400, ... parameter is invalid') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
186
        }
187
188
        $parameters = $this->constructSearchParameters($request);
189
        $results = $this->model->searchConcepts($parameters);
190
        $ret = $this->transformSearchResults($request, $results, $parameters);
191
192
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
193
    }
194
195
/** Vocabulary-specific methods **/
196
197
    /**
198
     * Loads the vocabulary metadata. And wraps the result in a json-ld object.
199
     * @param Request $request
200
     */
201
    public function vocabularyInformation($request)
202
    {
203
        $vocab = $request->getVocab();
204
        if ($this->notModified($vocab)) {
205
            return null;
206
        }
207
208
        /* encode the results in a JSON-LD compatible array */
209
        $conceptschemes = array();
210
        foreach ($vocab->getConceptSchemes($request->getLang()) as $uri => $csdata) {
211
            $csdata['uri'] = $uri;
212
            $csdata['type'] = 'skos:ConceptScheme';
213
            $conceptschemes[] = $csdata;
214
        }
215
216
        $ret = array(
217
            '@context' => array(
218
                'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
219
                'skos' => 'http://www.w3.org/2004/02/skos/core#',
220
                'onki' => 'http://schema.onki.fi/onki#',
221
                'dct' => 'http://purl.org/dc/terms/',
222
                'uri' => '@id',
223
                'type' => '@type',
224
                'conceptschemes' => 'onki:hasConceptScheme',
225
                'id' => 'onki:vocabularyIdentifier',
226
                'defaultLanguage' => 'onki:defaultLanguage',
227
                'languages' => 'onki:language',
228
                'label' => 'rdfs:label',
229
                'prefLabel' => 'skos:prefLabel',
230
                'title' => 'dct:title',
231
                '@language' => $request->getLang(),
232
                '@base' => $this->getBaseHref() . "rest/v1/" . $vocab->getId() . "/",
233
            ),
234
            'uri' => '',
235
            'id' => $vocab->getId(),
236
            'marcSource' => $vocab->getConfig()->getMarcSourceCode($request->getLang()),
237
            'title' => $vocab->getConfig()->getTitle($request->getLang()),
238
            'defaultLanguage' => $vocab->getConfig()->getDefaultLanguage(),
239
            'languages' => array_values($vocab->getConfig()->getLanguages()),
240
            'conceptschemes' => $conceptschemes,
241
        );
242
243
        if ($vocab->getConfig()->getTypes($request->getLang())) {
244
            $ret['type'] = $vocab->getConfig()->getTypes($request->getLang());
245
        }
246
247
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
248
    }
249
250
    /**
251
     * Loads the vocabulary metadata. And wraps the result in a json-ld object.
252
     * @param Request $request
253
     */
254
    public function vocabularyStatistics($request)
255
    {
256
        if ($this->notModified($request->getVocab())) {
257
            return null;
258
        }
259
        $this->setLanguageProperties($request->getLang());
260
        $arrayClass = $request->getVocab()->getConfig()->getArrayClassURI();
261
        $groupClass = $request->getVocab()->getConfig()->getGroupClassURI();
262
        $vocabStats = $request->getVocab()->getStatistics($request->getQueryParam('lang'), $arrayClass, $groupClass);
263
        $types = array('http://www.w3.org/2004/02/skos/core#Concept', 'http://www.w3.org/2004/02/skos/core#Collection', $arrayClass, $groupClass);
264
        $subTypes = array();
265
        foreach ($vocabStats as $subtype) {
266
            if (!in_array($subtype['type'], $types)) {
267
                $subTypes[] = $subtype;
268
            }
269
        }
270
271
        /* encode the results in a JSON-LD compatible array */
272
        $ret = array(
273
            '@context' => array(
274
                'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
275
                'skos' => 'http://www.w3.org/2004/02/skos/core#',
276
                'void' => 'http://rdfs.org/ns/void#',
277
                'onki' => 'http://schema.onki.fi/onki#',
278
                'uri' => '@id',
279
                'id' => 'onki:vocabularyIdentifier',
280
                'concepts' => 'void:classPartition',
281
                'label' => 'rdfs:label',
282
                'class' => array('@id' => 'void:class', '@type' => '@id'),
283
                'subTypes' => array('@id' => 'void:class', '@type' => '@id'),
284
                'count' => 'void:entities',
285
                '@language' => $request->getLang(),
286
                '@base' => $this->getBaseHref() . "rest/v1/" . $request->getVocab()->getId() . "/",
287
            ),
288
            'uri' => '',
289
            'id' => $request->getVocab()->getId(),
290
            'title' => $request->getVocab()->getConfig()->getTitle(),
291
            'concepts' => array(
292
                'class' => 'http://www.w3.org/2004/02/skos/core#Concept',
293
                'label' => gettext('skos:Concept'),
294
                'count' => isset($vocabStats['http://www.w3.org/2004/02/skos/core#Concept']) ? $vocabStats['http://www.w3.org/2004/02/skos/core#Concept']['count'] : 0,
295
            ),
296
            'subTypes' => $subTypes,
297
        );
298
299
        if (isset($vocabStats['http://www.w3.org/2004/02/skos/core#Collection'])) {
300
            $ret['conceptGroups'] = array(
301
                'class' => 'http://www.w3.org/2004/02/skos/core#Collection',
302
                'label' => gettext('skos:Collection'),
303
                'count' => $vocabStats['http://www.w3.org/2004/02/skos/core#Collection']['count'],
304
            );
305
        } else if (isset($vocabStats[$groupClass])) {
306
            $ret['conceptGroups'] = array(
307
                'class' => $groupClass,
308
                'label' => isset($vocabStats[$groupClass]['label']) ? $vocabStats[$groupClass]['label'] : gettext(EasyRdf\RdfNamespace::shorten($groupClass)),
309
                'count' => $vocabStats[$groupClass]['count'],
310
            );
311
        } else if (isset($vocabStats[$arrayClass])) {
312
            $ret['arrays'] = array(
313
                'class' => $arrayClass,
314
                'label' => isset($vocabStats[$arrayClass]['label']) ? $vocabStats[$arrayClass]['label'] : gettext(EasyRdf\RdfNamespace::shorten($arrayClass)),
315
                'count' => $vocabStats[$arrayClass]['count'],
316
            );
317
        }
318
319
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
320
    }
321
322
    /**
323
     * Loads the vocabulary metadata. And wraps the result in a json-ld object.
324
     * @param Request $request
325
     */
326
    public function labelStatistics($request)
327
    {
328
        if ($this->notModified($request->getVocab())) {
329
            return null;
330
        }
331
        $lang = $request->getLang();
332
        $this->setLanguageProperties($request->getLang());
333
        $vocabStats = $request->getVocab()->getLabelStatistics();
334
335
        /* encode the results in a JSON-LD compatible array */
336
        $counts = array();
337
        foreach ($vocabStats['terms'] as $proplang => $properties) {
338
            $langdata = array('language' => $proplang);
339
            if ($lang) {
340
                $langdata['literal'] = Punic\Language::getName($proplang, $lang);
341
            }
342
343
            $langdata['properties'] = array();
344
            foreach ($properties as $prop => $value) {
345
                $langdata['properties'][] = array('property' => $prop, 'labels' => $value);
346
            }
347
            $counts[] = $langdata;
348
        }
349
350
        $ret = array(
351
            '@context' => array(
352
                'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
353
                'skos' => 'http://www.w3.org/2004/02/skos/core#',
354
                'void' => 'http://rdfs.org/ns/void#',
355
                'void-ext' => 'http://ldf.fi/void-ext#',
356
                'onki' => 'http://schema.onki.fi/onki#',
357
                'uri' => '@id',
358
                'id' => 'onki:vocabularyIdentifier',
359
                'languages' => 'void-ext:languagePartition',
360
                'language' => 'void-ext:language',
361
                'properties' => 'void:propertyPartition',
362
                'labels' => 'void:triples',
363
                '@base' => $this->getBaseHref() . "rest/v1/" . $request->getVocab()->getId() . "/",
364
            ),
365
            'uri' => '',
366
            'id' => $request->getVocab()->getId(),
367
            'title' => $request->getVocab()->getConfig()->getTitle($lang),
368
            'languages' => $counts,
369
        );
370
371
        if ($lang) {
372
            $ret['@context']['literal'] = array('@id' => 'rdfs:label', '@language' => $lang);
373
        }
374
375
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
376
    }
377
378
    /**
379
     * Loads the vocabulary type metadata. And wraps the result in a json-ld object.
380
     * @param Request $request
381
     */
382
    public function types($request)
383
    {
384
        $vocid = $request->getVocab() ? $request->getVocab()->getId() : null;
385
        if ($vocid === null && !$request->getLang()) {
386
            return $this->returnError(400, "Bad Request", "lang parameter missing");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(400, ...ang parameter missing') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
387
        }
388
        if ($this->notModified($request->getVocab())) {
389
            return null;
390
        }
391
392
        $this->setLanguageProperties($request->getLang());
393
394
        $queriedtypes = $this->model->getTypes($vocid, $request->getLang());
395
396
        $types = array();
397
398
        /* encode the results in a JSON-LD compatible array */
399
        foreach ($queriedtypes as $uri => $typedata) {
400
            $type = array_merge(array('uri' => $uri), $typedata);
401
            $types[] = $type;
402
        }
403
404
        $base = $request->getVocab() ? $this->getBaseHref() . "rest/v1/" . $request->getVocab()->getId() . "/" : $this->getBaseHref() . "rest/v1/";
405
406
        $ret = array_merge_recursive($this->context, array(
407
            '@context' => array(
408
                'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
409
                'onki' => 'http://schema.onki.fi/onki#',
410
                'label' => 'rdfs:label',
411
                'superclass' => array('@id' => 'rdfs:subClassOf', '@type' => '@id'),
412
                'types' => 'onki:hasType',
413
                '@language' => $request->getLang(),
414
                '@base' => $base,
415
            ),
416
            'uri' => '',
417
            'types' => $types)
418
        );
419
420
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
421
    }
422
423
    private function findLookupHits($results, $label, $lang)
424
    {
425
        $hits = array();
426
        // case 1: exact match on preferred label
427
        foreach ($results as $res) {
428
            if (isset($res['prefLabel']) && $res['prefLabel'] == $label) {
429
                $hits[] = $res;
430
            }
431
        }
432
        if (sizeof($hits) > 0) return $hits;
433
434
        // case 2: case-insensitive match on preferred label
435
        foreach ($results as $res) {
436
            if (isset($res['prefLabel']) && strtolower($res['prefLabel']) == strtolower($label)) {
437
                $hits[] = $res;
438
            }
439
        }
440
        if (sizeof($hits) > 0) return $hits;
441
442
        if ($lang === null) {
443
            // case 1A: exact match on preferred label in any language
444
            foreach ($results as $res) {
445
                if (isset($res['matchedPrefLabel']) && $res['matchedPrefLabel']  == $label) {
446
                    $res['prefLabel'] = $res['matchedPrefLabel'];
447
                    unset($res['matchedPrefLabel']);
448
                    $hits[] = $res;
449
                }
450
            }
451
            if (sizeof($hits) > 0) return $hits;
452
453
            // case 2A: case-insensitive match on preferred label in any language
454
            foreach ($results as $res) {
455
                if (isset($res['matchedPrefLabel']) && strtolower($res['matchedPrefLabel']) == strtolower($label)) {
456
                    $res['prefLabel'] = $res['matchedPrefLabel'];
457
                    unset($res['matchedPrefLabel']);
458
                    $hits[] = $res;
459
                }
460
            }
461
            if (sizeof($hits) > 0) return $hits;
462
        }
463
464
        // case 3: exact match on alternate label
465
        foreach ($results as $res) {
466
            if (isset($res['altLabel']) && $res['altLabel'] == $label) {
467
                $hits[] = $res;
468
            }
469
        }
470
        if (sizeof($hits) > 0) return $hits;
471
472
473
        // case 4: case-insensitive match on alternate label
474
        foreach ($results as $res) {
475
            if (isset($res['altLabel']) && strtolower($res['altLabel']) == strtolower($label)) {
476
                $hits[] = $res;
477
            }
478
        }
479
        if (sizeof($hits) > 0) return $hits;
480
481
        return $hits;
482
    }
483
484
    private function transformLookupResults($lang, $hits)
485
    {
486
        if (sizeof($hits) == 0) {
487
            // no matches found
488
            return;
489
        }
490
491
        // found matches, getting rid of Vocabulary objects
492
        foreach ($hits as &$res) {
493
            unset($res['voc']);
494
        }
495
496
        $ret = array_merge_recursive($this->context, array(
497
            '@context' => array('onki' => 'http://schema.onki.fi/onki#', 'results' => array('@id' => 'onki:results'), 'prefLabel' => 'skos:prefLabel', 'altLabel' => 'skos:altLabel', 'hiddenLabel' => 'skos:hiddenLabel'),
498
            'result' => $hits)
499
        );
500
501
        if ($lang) {
502
            $ret['@context']['@language'] = $lang;
503
        }
504
505
        return $ret;
506
    }
507
508
    /**
509
     * Used for finding terms by their exact prefLabel. Wraps the result in a json-ld object.
510
     * @param Request $request
511
     */
512
    public function lookup($request)
513
    {
514
        $label = $request->getQueryParamRaw('label');
515
        if (!$label) {
516
            return $this->returnError(400, "Bad Request", "label parameter missing");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(400, ...bel parameter missing') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
517
        }
518
519
        $lang = $request->getQueryParam('lang');
520
        $parameters = new ConceptSearchParameters($request, $this->model->getConfig(), true);
521
        $results = $this->model->searchConcepts($parameters);
522
        $hits = $this->findLookupHits($results, $label, $lang);
523
        $ret = $this->transformLookupResults($lang, $hits);
524
        if ($ret === null) {
525
            return $this->returnError(404, 'Not Found', "Could not find label '$label'");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(404, ...nd label ''.$label.''') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
526
        }
527
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
528
    }
529
530
    /**
531
     * Queries the top concepts of a vocabulary and wraps the results in a json-ld object.
532
     * @param Request $request
533
     * @return object json-ld object
534
     */
535
    public function topConcepts($request)
536
    {
537
        $vocab = $request->getVocab();
538
        if ($this->notModified($vocab)) {
539
            return null;
540
        }
541
        $scheme = $request->getQueryParam('scheme');
542
        if (!$scheme) {
543
            $scheme = $vocab->getConfig()->showConceptSchemesInHierarchy() ? array_keys($vocab->getConceptSchemes()) : $vocab->getDefaultConceptScheme();
544
        }
545
546
        /* encode the results in a JSON-LD compatible array */
547
        $topconcepts = $vocab->getTopConcepts($scheme, $request->getLang());
0 ignored issues
show
Bug introduced by
It seems like $scheme can also be of type array; however, parameter $conceptScheme of Vocabulary::getTopConcepts() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

547
        $topconcepts = $vocab->getTopConcepts(/** @scrutinizer ignore-type */ $scheme, $request->getLang());
Loading history...
548
549
        $ret = array_merge_recursive($this->context, array(
550
            '@context' => array('onki' => 'http://schema.onki.fi/onki#', 'topconcepts' => 'skos:hasTopConcept', 'notation' => 'skos:notation', 'label' => 'skos:prefLabel', '@language' => $request->getLang()),
551
            'uri' => $scheme,
552
            'topconcepts' => $topconcepts)
553
        );
554
555
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
556
    }
557
558
    private function redirectToVocabData($request) {
559
        $urls = $request->getVocab()->getConfig()->getDataURLs();
560
        if (sizeof($urls) == 0) {
561
            $vocid = $request->getVocab()->getId();
562
            return $this->returnError('404', 'Not Found', "No download source URL known for vocabulary $vocid");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError('404'...or vocabulary '.$vocid) targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
563
        }
564
565
        $format = $this->negotiateFormat(array_keys($urls), $request->getServerConstant('HTTP_ACCEPT'), $request->getQueryParam('format'));
566
        if (!$format) {
567
            return $this->returnError(406, 'Not Acceptable', "Unsupported format. Supported MIME types are: " . implode(' ', array_keys($urls)));
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(406, ... ', array_keys($urls))) targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
568
        }
569
        if (is_array($urls[$format])) {
570
            $arr = $urls[$format];
571
            $dataLang = $request->getLang();
572
            if (isset($arr[$dataLang])) {
573
                header("Location: " . $arr[$dataLang]);
574
            } else {
575
                $vocid = $request->getVocab()->getId();
576
                return $this->returnError('404', 'Not Found', "No download source URL known for vocabulary $vocid in language $dataLang");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError('404'...n language '.$dataLang) targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
577
            }
578
		} else {
579
            header("Location: " . $urls[$format]);
580
		}
581
    }
582
583
    private function returnDataResults($results, $format) {
584
        if ($format == 'application/ld+json' || $format == 'application/json') {
585
            // further compact JSON-LD document using a context
586
            $context = array(
587
                'skos' => 'http://www.w3.org/2004/02/skos/core#',
588
                'isothes' => 'http://purl.org/iso25964/skos-thes#',
589
                'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
590
                'owl' => 'http://www.w3.org/2002/07/owl#',
591
                'dct' => 'http://purl.org/dc/terms/',
592
                'dc11' => 'http://purl.org/dc/elements/1.1/',
593
                'uri' => '@id',
594
                'type' => '@type',
595
                'lang' => '@language',
596
                'value' => '@value',
597
                'graph' => '@graph',
598
                'label' => 'rdfs:label',
599
                'prefLabel' => 'skos:prefLabel',
600
                'altLabel' => 'skos:altLabel',
601
                'hiddenLabel' => 'skos:hiddenLabel',
602
                'broader' => 'skos:broader',
603
                'narrower' => 'skos:narrower',
604
                'related' => 'skos:related',
605
                'inScheme' => 'skos:inScheme',
606
                'exactMatch' => 'skos:exactMatch',
607
                'closeMatch' => 'skos:closeMatch',
608
                'broadMatch' => 'skos:broadMatch',
609
                'narrowMatch' => 'skos:narrowMatch',
610
                'relatedMatch' => 'skos:relatedMatch',
611
            );
612
            $compactJsonLD = \ML\JsonLD\JsonLD::compact($results, json_encode($context));
613
            $results = \ML\JsonLD\JsonLD::toString($compactJsonLD);
614
        }
615
616
        header("Content-type: $format; charset=utf-8");
617
        echo $results;
618
    }
619
620
    /**
621
     * Download a concept as json-ld or redirect to download the whole vocabulary.
622
     * @param Request $request
623
     * @return object json-ld formatted concept.
624
     */
625
    public function data($request)
626
    {
627
        $vocab = $request->getVocab();
628
        if ($this->notModified($request->getVocab())) {
629
            return null;
630
        }
631
632
        if ($request->getUri()) {
633
            $uri = $request->getUri();
634
        } else if ($vocab !== null) { // whole vocabulary - redirect to download URL
635
            return $this->redirectToVocabData($request);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->redirectToVocabData($request) targeting RestController::redirectToVocabData() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
636
        } else {
637
            return $this->returnError(400, 'Bad Request', "uri parameter missing");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(400, ...uri parameter missing') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
638
        }
639
640
        $format = $this->negotiateFormat(explode(' ', self::SUPPORTED_FORMATS), $request->getServerConstant('HTTP_ACCEPT'), $request->getQueryParam('format'));
641
        if (!$format) {
642
            return $this->returnError(406, 'Not Acceptable', "Unsupported format. Supported MIME types are: " . self::SUPPORTED_FORMATS);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(406, ...elf::SUPPORTED_FORMATS) targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
643
        }
644
645
        $vocid = $vocab ? $vocab->getId() : null;
0 ignored issues
show
introduced by
$vocab is of type Vocabulary, thus it always evaluated to true.
Loading history...
646
        $results = $this->model->getRDF($vocid, $uri, $format);
647
        if (empty($results)) {
648
            return $this->returnError(404, 'Bad Request', "no concept found with given uri");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(404, ... found with given uri') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
649
        }
650
        return $this->returnDataResults($results, $format);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnDataResults($results, $format) targeting RestController::returnDataResults() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
651
    }
652
653
    /**
654
     * Get the mappings associated with a concept, enriched with labels and notations.
655
     * Returns a JSKOS-compatible JSON object.
656
     * @param Request $request
657
     * @throws Exception if the vocabulary ID is not found in configuration
658
     */
659
    public function mappings(Request $request)
660
    {
661
        $this->setLanguageProperties($request->getLang());
662
        $vocab = $request->getVocab();
663
        if ($this->notModified($vocab)) {
664
            return null;
665
        }
666
667
        $uri = $request->getUri();
668
        if (!$uri) {
669
            return $this->returnError(400, 'Bad Request', "uri parameter missing");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(400, ...uri parameter missing') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
670
        }
671
672
        $queryExVocabs = $request->getQueryParamBoolean('external', true);
673
674
        $results = $vocab->getConceptInfo($uri, $request->getContentLang());
675
        if (empty($results)) {
676
            return $this->returnError(404, 'Bad Request', "no concept found with given uri");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(404, ... found with given uri') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
677
        }
678
679
        $concept = $results[0];
680
681
        $mappings = [];
682
        foreach ($concept->getMappingProperties() as $mappingProperty) {
683
            foreach ($mappingProperty->getValues() as $mappingPropertyValue) {
684
                $hrefLink = $this->linkUrlFilter($mappingPropertyValue->getUri(), $mappingPropertyValue->getExVocab(), $request->getLang(), 'page', $request->getContentLang());
685
                $mappings[] = $mappingPropertyValue->asJskos($queryExVocabs, $request->getLang(), $hrefLink);
686
            }
687
        }
688
689
        $ret = array(
690
            'mappings' => $mappings,
691
            'graph' => $concept->dumpJsonLd()
692
        );
693
694
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
695
    }
696
697
    /**
698
     * Used for querying labels for a uri.
699
     * @param Request $request
700
     * @return object json-ld wrapped labels.
701
     */
702
    public function label($request)
703
    {
704
        if (!$request->getUri()) {
705
            return $this->returnError(400, "Bad Request", "uri parameter missing");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError(400, ...uri parameter missing') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
706
        }
707
708
        if ($this->notModified($request->getVocab())) {
709
            return null;
710
        }
711
712
        $vocab = $request->getVocab();
713
        if ($vocab === null) {
714
            $vocab = $this->model->guessVocabularyFromUri($request->getUri());
715
        }
716
        if ($vocab === null) {
717
            return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError('404'...$request->getUri().'>') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
718
        }
719
720
        $labelResults = $vocab->getAllConceptLabels($request->getUri(), $request->getLang());
721
        if ($labelResults === null) {
0 ignored issues
show
introduced by
The condition $labelResults === null is always false.
Loading history...
722
            return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>");
723
        }
724
725
        // there should be only one preferred label so no need for an array
726
        if (array_key_exists('prefLabel', $labelResults)) {
727
            $labelResults['prefLabel'] = $labelResults['prefLabel'][0];
728
        }
729
730
        $ret = array_merge_recursive($this->context,
731
                                    array('@context' => array('prefLabel' => 'skos:prefLabel', 'altLabel' => 'skos:altLabel', 'hiddenLabel' => 'skos:hiddenLabel', '@language' => $request->getLang()),
732
                                    'uri' => $request->getUri()),
733
                                    $labelResults);
734
735
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
736
    }
737
738
    /**
739
     * Query for the available letters in the alphabetical index.
740
     * @param Request $request
741
     * @return object JSON-LD wrapped list of letters
742
     */
743
744
    public function indexLetters($request)
745
    {
746
        $this->setLanguageProperties($request->getLang());
747
        $letters = $request->getVocab()->getAlphabet($request->getLang());
748
749
        $ret = array_merge_recursive($this->context, array(
750
            '@context' => array(
751
                'indexLetters' => array(
752
                    '@id' => 'skosmos:indexLetters',
753
                    '@container' => '@list',
754
                    '@language' => $request->getLang()
755
                )
756
            ),
757
            'uri' => '',
758
            'indexLetters' => $letters)
759
        );
760
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
761
    }
762
763
    /**
764
     * Query for the concepts with terms starting with a given letter in the
765
     * alphabetical index.
766
     * @param Request $request
767
     * @return object JSON-LD wrapped list of terms/concepts
768
     */
769
770
    public function indexConcepts($letter, $request)
771
    {
772
        $this->setLanguageProperties($request->getLang());
773
774
        $offset_param = $request->getQueryParam('offset');
775
        $offset = (is_numeric($offset_param) && $offset_param >= 0) ? $offset_param : 0;
776
        $limit_param = $request->getQueryParam('limit');
777
        $limit = (is_numeric($limit_param) && $limit_param >= 0) ? $limit_param : 0;
778
779
        $concepts = $request->getVocab()->searchConceptsAlphabetical($letter, $limit, $offset, $request->getLang());
780
781
        $ret = array_merge_recursive($this->context, array(
782
            '@context' => array(
783
                'indexConcepts' => array(
784
                    '@id' => 'skosmos:indexConcepts',
785
                    '@container' => '@list'
786
                )
787
            ),
788
            'uri' => '',
789
            'indexConcepts' => $concepts)
790
        );
791
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
792
    }
793
794
    private function transformPropertyResults($uri, $lang, $objects, $propname, $propuri)
795
    {
796
        $results = array();
797
        foreach ($objects as $objuri => $vals) {
798
            $results[] = array('uri' => $objuri, 'prefLabel' => $vals['label']);
799
        }
800
801
        return array_merge_recursive($this->context, array(
802
            '@context' => array('prefLabel' => 'skos:prefLabel', $propname => $propuri, '@language' => $lang),
803
            'uri' => $uri,
804
            $propname => $results)
805
        );
806
    }
807
808
    private function transformTransitivePropertyResults($uri, $lang, $objects, $tpropname, $tpropuri, $dpropname, $dpropuri)
809
    {
810
        $results = array();
811
        foreach ($objects as $objuri => $vals) {
812
            $result = array('uri' => $objuri, 'prefLabel' => $vals['label']);
813
            if (isset($vals['direct'])) {
814
                $result[$dpropname] = $vals['direct'];
815
            }
816
            $results[$objuri] = $result;
817
        }
818
819
        return array_merge_recursive($this->context, array(
820
            '@context' => array('prefLabel' => 'skos:prefLabel', $dpropname => array('@id' => $dpropuri, '@type' => '@id'), $tpropname => array('@id' => $tpropuri, '@container' => '@index'), '@language' => $lang),
821
            'uri' => $uri,
822
            $tpropname => $results)
823
        );
824
    }
825
826
    /**
827
     * Used for querying broader relations for a concept.
828
     * @param Request $request
829
     * @return object json-ld wrapped broader concept uris and labels.
830
     */
831
    public function broader($request)
832
    {
833
        if ($this->notModified($request->getVocab())) {
834
            return null;
835
        }
836
        $broaders = $request->getVocab()->getConceptBroaders($request->getUri(), $request->getLang());
837
        if ($broaders === null) {
0 ignored issues
show
introduced by
The condition $broaders === null is always false.
Loading history...
838
            return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>");
839
        }
840
        $ret = $this->transformPropertyResults($request->getUri(), $request->getLang(), $broaders, "broader", "skos:broader");
841
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
842
    }
843
844
    /**
845
     * Used for querying broader transitive relations for a concept.
846
     * @param Request $request
847
     * @return object json-ld wrapped broader transitive concept uris and labels.
848
     */
849
    public function broaderTransitive($request)
850
    {
851
        if ($this->notModified($request->getVocab())) {
852
            return null;
853
        }
854
        $broaders = $request->getVocab()->getConceptTransitiveBroaders($request->getUri(), $this->parseLimit(), false, $request->getLang());
855
        if (empty($broaders)) {
856
            return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError('404'...$request->getUri().'>') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
857
        }
858
        $ret = $this->transformTransitivePropertyResults($request->getUri(), $request->getLang(), $broaders, "broaderTransitive", "skos:broaderTransitive", "broader", "skos:broader");
859
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
860
    }
861
862
    /**
863
     * Used for querying narrower relations for a concept.
864
     * @param Request $request
865
     * @return object json-ld wrapped narrower concept uris and labels.
866
     */
867
    public function narrower($request)
868
    {
869
        if ($this->notModified($request->getVocab())) {
870
            return null;
871
        }
872
        $narrowers = $request->getVocab()->getConceptNarrowers($request->getUri(), $request->getLang());
873
        if ($narrowers === null) {
0 ignored issues
show
introduced by
The condition $narrowers === null is always false.
Loading history...
874
            return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>");
875
        }
876
        $ret = $this->transformPropertyResults($request->getUri(), $request->getLang(), $narrowers, "narrower", "skos:narrower");
877
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
878
    }
879
880
    /**
881
     * Used for querying narrower transitive relations for a concept.
882
     * @param Request $request
883
     * @return object json-ld wrapped narrower transitive concept uris and labels.
884
     */
885
    public function narrowerTransitive($request)
886
    {
887
        if ($this->notModified($request->getVocab())) {
888
            return null;
889
        }
890
        $narrowers = $request->getVocab()->getConceptTransitiveNarrowers($request->getUri(), $this->parseLimit(), $request->getLang());
891
        if (empty($narrowers)) {
892
            return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError('404'...$request->getUri().'>') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
893
        }
894
        $ret = $this->transformTransitivePropertyResults($request->getUri(), $request->getLang(), $narrowers, "narrowerTransitive", "skos:narrowerTransitive", "narrower", "skos:narrower");
895
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
896
    }
897
898
    /**
899
     * Used for querying broader transitive relations
900
     * and some narrowers for a concept in the hierarchy view.
901
     * @param Request $request
902
     * @return object json-ld wrapped hierarchical concept uris and labels.
903
     */
904
    public function hierarchy($request)
905
    {
906
        if ($this->notModified($request->getVocab())) {
907
            return null;
908
        }
909
        $results = $request->getVocab()->getConceptHierarchy($request->getUri(), $request->getLang());
910
        if (empty($results)) {
911
            return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError('404'...$request->getUri().'>') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
912
        }
913
914
        // set the "top" key from the "tops" key
915
        foreach ($results as $value) {
916
            $uri = $value['uri'];
917
            if (isset($value['tops'])) {
918
                if ($request->getVocab()->getConfig()->getMainConceptSchemeURI() != null) {
919
                    foreach ($results[$uri]['tops'] as $top) {
920
                        // if a value in 'tops' matches the main concept scheme of the vocabulary, take it
921
                        if ($top == $request->getVocab()->getConfig()->getMainConceptSchemeURI()) {
922
                            $results[$uri]['top'] = $top;
923
                            break;
924
                        }
925
                    }
926
                    // if the main concept scheme was not found, set 'top' to the first 'tops' (sorted alphabetically on the URIs)
927
                    if (! isset($results[$uri]['top'])) {
928
                        $results[$uri]['top'] = $results[$uri]['tops'][0];
929
                    }
930
                } else {
931
                    // no main concept scheme set on the vocab, take the first value of 'tops' (sorted alphabetically)
932
                    $results[$uri]['top'] = $results[$uri]['tops'][0];
933
                }
934
            }
935
        }
936
937
        if ($request->getVocab()->getConfig()->getShowHierarchy()) {
938
            $schemes = $request->getVocab()->getConceptSchemes($request->getLang());
939
            foreach ($schemes as $scheme) {
940
                if (!isset($scheme['title']) && !isset($scheme['label']) && !isset($scheme['prefLabel'])) {
941
                    unset($schemes[array_search($scheme, $schemes)]);
942
                }
943
944
            }
945
946
            /* encode the results in a JSON-LD compatible array */
947
            $topconcepts = $request->getVocab()->getTopConcepts(array_keys($schemes), $request->getLang());
0 ignored issues
show
Bug introduced by
array_keys($schemes) of type array is incompatible with the type string expected by parameter $conceptScheme of Vocabulary::getTopConcepts(). ( Ignorable by Annotation )

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

947
            $topconcepts = $request->getVocab()->getTopConcepts(/** @scrutinizer ignore-type */ array_keys($schemes), $request->getLang());
Loading history...
948
            foreach ($topconcepts as $top) {
949
                if (!isset($results[$top['uri']])) {
950
                    $results[$top['uri']] = array('uri' => $top['uri'], 'top'=>$top['topConceptOf'], 'tops'=>array($top['topConceptOf']), 'prefLabel' => $top['label'], 'hasChildren' => $top['hasChildren']);
951
                    if (isset($top['notation'])) {
952
                        $results[$top['uri']]['notation'] = $top['notation'];
953
                    }
954
955
                }
956
            }
957
        }
958
959
        $ret = array_merge_recursive($this->context, array(
960
            '@context' => array(
961
                'onki' => 'http://schema.onki.fi/onki#',
962
                'prefLabel' => 'skos:prefLabel',
963
                'notation' => 'skos:notation',
964
                'narrower' => array('@id' => 'skos:narrower', '@type' => '@id'),
965
                'broader' => array('@id' => 'skos:broader', '@type' => '@id'),
966
                'broaderTransitive' => array('@id' => 'skos:broaderTransitive', '@container' => '@index'),
967
                'top' => array('@id' => 'skos:topConceptOf', '@type' => '@id'),
968
                // the tops key will contain all the concept scheme values, while top (singular) contains a single value
969
                'tops' => array('@id' => 'skos:topConceptOf', '@type' => '@id'),
970
                'hasChildren' => 'onki:hasChildren',
971
                '@language' => $request->getLang()
972
            ),
973
            'uri' => $request->getUri(),
974
            'broaderTransitive' => $results)
975
        );
976
977
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
978
    }
979
980
    /**
981
     * Used for querying group hierarchy for the sidebar group view.
982
     * @param Request $request
983
     * @return object json-ld wrapped hierarchical concept uris and labels.
984
     */
985
    public function groups($request)
986
    {
987
        if ($this->notModified($request->getVocab())) {
988
            return null;
989
        }
990
        $results = $request->getVocab()->listConceptGroups($request->getLang());
991
992
        $ret = array_merge_recursive($this->context, array(
993
            '@context' => array('onki' => 'http://schema.onki.fi/onki#', 'prefLabel' => 'skos:prefLabel', 'groups' => 'onki:hasGroup', 'childGroups' => array('@id' => 'skos:member', '@type' => '@id'), 'hasMembers' => 'onki:hasMembers', '@language' => $request->getLang()),
994
            'uri' => '',
995
            'groups' => $results)
996
        );
997
998
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
999
    }
1000
1001
    /**
1002
     * Used for querying member relations for a group.
1003
     * @param Request $request
1004
     * @return object json-ld wrapped narrower concept uris and labels.
1005
     */
1006
    public function groupMembers($request)
1007
    {
1008
        if ($this->notModified($request->getVocab())) {
1009
            return null;
1010
        }
1011
        $children = $request->getVocab()->listConceptGroupContents($request->getUri(), $request->getLang());
1012
        if (empty($children)) {
1013
            return $this->returnError('404', 'Not Found', "Could not find group <{$request->getUri()}>");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnError('404'...$request->getUri().'>') targeting Controller::returnError() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
1014
        }
1015
1016
        $ret = array_merge_recursive($this->context, array(
1017
            '@context' => array('prefLabel' => 'skos:prefLabel', 'members' => 'skos:member', '@language' => $request->getLang()),
1018
            'uri' => $request->getUri(),
1019
            'members' => $children)
1020
        );
1021
1022
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
1023
    }
1024
1025
    /**
1026
     * Used for querying narrower relations for a concept in the hierarchy view.
1027
     * @param Request $request
1028
     * @return object json-ld wrapped narrower concept uris and labels.
1029
     */
1030
    public function children($request)
1031
    {
1032
        if ($this->notModified($request->getVocab())) {
1033
            return null;
1034
        }
1035
        $children = $request->getVocab()->getConceptChildren($request->getUri(), $request->getLang());
1036
        if ($children === null) {
0 ignored issues
show
introduced by
The condition $children === null is always false.
Loading history...
1037
            return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>");
1038
        }
1039
1040
        $ret = array_merge_recursive($this->context, array(
1041
            '@context' => array('prefLabel' => 'skos:prefLabel', 'narrower' => 'skos:narrower', 'notation' => 'skos:notation', 'hasChildren' => 'onki:hasChildren', '@language' => $request->getLang()),
1042
            'uri' => $request->getUri(),
1043
            'narrower' => $children)
1044
        );
1045
1046
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
1047
    }
1048
1049
    /**
1050
     * Used for querying narrower relations for a concept in the hierarchy view.
1051
     * @param Request $request
1052
     * @return object json-ld wrapped hierarchical concept uris and labels.
1053
     */
1054
    public function related($request)
1055
    {
1056
        if ($this->notModified($request->getVocab())) {
1057
            return null;
1058
        }
1059
        $related = $request->getVocab()->getConceptRelateds($request->getUri(), $request->getLang());
1060
        if ($related === null) {
0 ignored issues
show
introduced by
The condition $related === null is always false.
Loading history...
1061
            return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>");
1062
        }
1063
        $ret = $this->transformPropertyResults($request->getUri(), $request->getLang(), $related, "related", "skos:related");
1064
        return $this->returnJson($ret);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson($ret) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
1065
    }
1066
1067
    /**
1068
     * Used for querying new concepts in the vocabulary
1069
     * @param Request $request
1070
     * @return object json-ld wrapped list of changed concepts
1071
     */
1072
    public function newConcepts($request)
1073
    {
1074
        $offset = ($request->getQueryParam('offset') && is_numeric($request->getQueryParam('offset')) && $request->getQueryParam('offset') >= 0) ? $request->getQueryParam('offset') : 0;
1075
        $limit = ($request->getQueryParam('limit') && is_numeric($request->getQueryParam('limit')) && $request->getQueryParam('limit') >= 0) ? $request->getQueryParam('limit') : 200;
1076
1077
        return $this->changedConcepts($request, 'dc:created', $offset, $limit);
0 ignored issues
show
Bug introduced by
It seems like $offset can also be of type string; however, parameter $offset of RestController::changedConcepts() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

1077
        return $this->changedConcepts($request, 'dc:created', /** @scrutinizer ignore-type */ $offset, $limit);
Loading history...
Bug introduced by
It seems like $limit can also be of type string; however, parameter $limit of RestController::changedConcepts() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

1077
        return $this->changedConcepts($request, 'dc:created', $offset, /** @scrutinizer ignore-type */ $limit);
Loading history...
1078
    }
1079
1080
    /**
1081
     * Used for querying modified concepts in the vocabulary
1082
     * @param Request $request
1083
     * @return object json-ld wrapped list of changed concepts
1084
     */
1085
    public function modifiedConcepts($request)
1086
    {
1087
        $offset = ($request->getQueryParam('offset') && is_numeric($request->getQueryParam('offset')) && $request->getQueryParam('offset') >= 0) ? $request->getQueryParam('offset') : 0;
1088
        $limit = ($request->getQueryParam('limit') && is_numeric($request->getQueryParam('limit')) && $request->getQueryParam('limit') >= 0) ? $request->getQueryParam('limit') : 200;
1089
1090
        return $this->changedConcepts($request, 'dc:modified', $offset, $limit);
0 ignored issues
show
Bug introduced by
It seems like $limit can also be of type string; however, parameter $limit of RestController::changedConcepts() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

1090
        return $this->changedConcepts($request, 'dc:modified', $offset, /** @scrutinizer ignore-type */ $limit);
Loading history...
Bug introduced by
It seems like $offset can also be of type string; however, parameter $offset of RestController::changedConcepts() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

1090
        return $this->changedConcepts($request, 'dc:modified', /** @scrutinizer ignore-type */ $offset, $limit);
Loading history...
1091
    }
1092
1093
    /**
1094
     * Used for querying changed concepts in the vocabulary
1095
     * @param Request $request
1096
     * @param int $offset starting index offset
1097
     * @param int $limit maximum number of concepts to return
1098
     * @return object json-ld wrapped list of changed concepts
1099
     */
1100
    private function changedConcepts($request, $prop, $offset, $limit)
1101
    {
1102
        $changeList = $request->getVocab()->getChangeList($prop, $request->getLang(), $offset, $limit);
1103
1104
        $simpleChangeList = array();
1105
        foreach($changeList as $conceptInfo) {
1106
            if (array_key_exists('date', $conceptInfo)) {
1107
                $simpleChangeList[] =  array( 'uri' => $conceptInfo['uri'],
1108
                                               'prefLabel' => $conceptInfo['prefLabel'],
1109
                                               'date' => $conceptInfo['date']->format("Y-m-d\TH:i:sO") );
1110
            }
1111
        }
1112
        return $this->returnJson(array_merge_recursive($this->context,
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->returnJson(array_...=> $simpleChangeList))) targeting RestController::returnJson() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
1113
                                                        array('@context' => array( '@language' => $request->getLang(),
1114
                                                                                     'prefLabel' => 'skos:prefLabel',
1115
                                                                                     'xsd' => 'http://www.w3.org/2001/XMLSchema#',
1116
                                                                                     'date' => array( '@id' => 'http://purl.org/dc/terms/date', '@type' => 'http://www.w3.org/2001/XMLSchema#dateTime') )
1117
                                                        ),
1118
                                                        array('changeList' => $simpleChangeList)));
1119
1120
    }
1121
}
1122