|
1
|
|
|
<?php |
|
|
|
|
|
|
2
|
|
|
/** |
|
3
|
|
|
* Copyright (c) 2012-2013 Aalto University and University of Helsinki |
|
4
|
|
|
* MIT License |
|
5
|
|
|
* see LICENSE.txt for more information |
|
6
|
|
|
*/ |
|
7
|
|
|
|
|
8
|
|
|
/** |
|
9
|
|
|
* Rest controller is an extension of the controller so that must be imported. |
|
10
|
|
|
*/ |
|
11
|
|
|
require_once 'controller/Controller.php'; |
|
12
|
|
|
|
|
13
|
|
|
/** |
|
14
|
|
|
* RestController is responsible for handling all the requests directed to the /rest address. |
|
15
|
|
|
*/ |
|
16
|
|
|
class RestController extends Controller |
|
|
|
|
|
|
17
|
|
|
{ |
|
18
|
|
|
/* supported MIME types that can be used to return RDF data */ |
|
19
|
|
|
private static $SUPPORTED_MIME_TYPES = 'application/rdf+xml text/turtle application/ld+json application/json'; |
|
20
|
|
|
/* context array template */ |
|
21
|
|
|
private $context = array( |
|
22
|
|
|
'@context' => array( |
|
23
|
|
|
'skos' => 'http://www.w3.org/2004/02/skos/core#', |
|
24
|
|
|
'uri' => '@id', |
|
25
|
|
|
'type' => '@type', |
|
26
|
|
|
), |
|
27
|
|
|
); |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* Echos an error message when the request can't be fulfilled. |
|
31
|
|
|
* @param string $code |
|
32
|
|
|
* @param string $status |
|
33
|
|
|
* @param string $message |
|
34
|
|
|
*/ |
|
35
|
|
|
private function returnError($code, $status, $message) |
|
36
|
|
|
{ |
|
37
|
|
|
header("HTTP/1.0 $code $status"); |
|
38
|
|
|
header("Content-type: text/plain; charset=utf-8"); |
|
39
|
|
|
echo "$code $status : $message"; |
|
40
|
|
|
} |
|
41
|
|
|
|
|
42
|
|
|
/** |
|
43
|
|
|
* Handles json encoding, adding the content type headers and optional callback function. |
|
44
|
|
|
* @param array $data the data to be returned. |
|
45
|
|
|
*/ |
|
46
|
|
|
private function returnJson($data) |
|
47
|
|
|
{ |
|
48
|
|
|
if (filter_input(INPUT_GET, 'callback', FILTER_SANITIZE_STRING)) { |
|
49
|
|
|
header("Content-type: application/javascript; charset=utf-8"); |
|
50
|
|
|
// wrap with JSONP callback |
|
51
|
|
|
echo filter_input(INPUT_GET, 'callback', FILTER_UNSAFE_RAW) . "(" . json_encode($data) . ");"; |
|
52
|
|
|
} else { |
|
53
|
|
|
// negotiate suitable format |
|
54
|
|
|
$negotiator = new \Negotiation\FormatNegotiator(); |
|
55
|
|
|
$priorities = array('application/json', 'application/ld+json'); |
|
56
|
|
|
$best = filter_input(INPUT_SERVER, 'HTTP_ACCEPT', FILTER_SANITIZE_STRING) ? $negotiator->getBest(filter_input(INPUT_SERVER, 'HTTP_ACCEPT', FILTER_SANITIZE_STRING), $priorities) : null; |
|
57
|
|
|
$format = ($best !== null) ? $best->getValue() : $priorities[0]; |
|
58
|
|
|
header("Content-type: $format; charset=utf-8"); |
|
59
|
|
|
header("Vary: Accept"); // inform caches that we made a choice based on Accept header |
|
60
|
|
|
echo json_encode($data); |
|
61
|
|
|
} |
|
62
|
|
|
} |
|
63
|
|
|
|
|
64
|
|
|
/** |
|
65
|
|
|
* Parses and returns the limit parameter. Returns and error if the parameter is missing. |
|
66
|
|
|
*/ |
|
67
|
|
|
private function parseLimit() |
|
68
|
|
|
{ |
|
69
|
|
|
$limit = filter_input(INPUT_GET, 'limit', FILTER_SANITIZE_NUMBER_INT) ? filter_input(INPUT_GET, 'limit', FILTER_SANITIZE_NUMBER_INT) : $this->model->getConfig()->getDefaultTransitiveLimit(); |
|
70
|
|
|
if ($limit <= 0) { |
|
71
|
|
|
return $this->returnError(400, "Bad Request", "Invalid limit parameter"); |
|
72
|
|
|
} |
|
73
|
|
|
|
|
74
|
|
|
return $limit; |
|
75
|
|
|
} |
|
76
|
|
|
|
|
77
|
|
|
/** |
|
78
|
|
|
* Negotiate a MIME type according to the proposed format, the list of valid |
|
79
|
|
|
* formats, and an optional proposed format. |
|
80
|
|
|
* As a side effect, set the HTTP Vary header if a choice was made based on |
|
81
|
|
|
* the Accept header. |
|
82
|
|
|
* @param array $choices possible MIME types as strings |
|
83
|
|
|
* @param string $accept HTTP Accept header value |
|
84
|
|
|
* @param string $format proposed format |
|
85
|
|
|
* @return string selected format, or null if negotiation failed |
|
86
|
|
|
*/ |
|
87
|
|
|
private function negotiateFormat($choices, $accept, $format) |
|
88
|
|
|
{ |
|
89
|
|
|
if ($format) { |
|
90
|
|
|
if (!in_array($format, $choices)) { |
|
91
|
|
|
return null; |
|
92
|
|
|
} |
|
93
|
|
|
|
|
94
|
|
|
} else { |
|
95
|
|
|
header('Vary: Accept'); // inform caches that a decision was made based on Accept header |
|
96
|
|
|
$best = $this->negotiator->getBest($accept, $choices); |
|
97
|
|
|
$format = ($best !== null) ? $best->getValue() : null; |
|
98
|
|
|
} |
|
99
|
|
|
return $format; |
|
100
|
|
|
} |
|
101
|
|
|
|
|
102
|
|
|
/** Global REST methods **/ |
|
103
|
|
|
|
|
104
|
|
|
/** |
|
105
|
|
|
* Returns all the vocabularies available on the server in a json object. |
|
106
|
|
|
*/ |
|
107
|
|
|
public function vocabularies($request) |
|
108
|
|
|
{ |
|
109
|
|
|
if (!$request->getLang()) { |
|
110
|
|
|
return $this->returnError(400, "Bad Request", "lang parameter missing"); |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
$this->setLanguageProperties($request->getLang()); |
|
114
|
|
|
|
|
115
|
|
|
$vocabs = array(); |
|
116
|
|
|
foreach ($this->model->getVocabularies() as $voc) { |
|
117
|
|
|
$vocabs[$voc->getId()] = $voc->getConfig()->getTitle($request->getLang()); |
|
118
|
|
|
} |
|
119
|
|
|
ksort($vocabs); |
|
120
|
|
|
$results = array(); |
|
121
|
|
|
foreach ($vocabs as $id => $title) { |
|
122
|
|
|
$results[] = array( |
|
123
|
|
|
'uri' => $id, |
|
124
|
|
|
'id' => $id, |
|
125
|
|
|
'title' => $title); |
|
126
|
|
|
} |
|
127
|
|
|
|
|
128
|
|
|
/* encode the results in a JSON-LD compatible array */ |
|
129
|
|
|
$ret = array( |
|
130
|
|
|
'@context' => array( |
|
131
|
|
|
'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#', |
|
132
|
|
|
'onki' => 'http://schema.onki.fi/onki#', |
|
133
|
|
|
'title' => array('@id' => 'rdfs:label', '@language' => $request->getLang()), |
|
134
|
|
|
'vocabularies' => 'onki:hasVocabulary', |
|
135
|
|
|
'id' => 'onki:vocabularyIdentifier', |
|
136
|
|
|
'uri' => '@id', |
|
137
|
|
|
), |
|
138
|
|
|
'uri' => '', |
|
139
|
|
|
'vocabularies' => $results, |
|
140
|
|
|
); |
|
141
|
|
|
|
|
142
|
|
|
return $this->returnJson($ret); |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
|
|
/** |
|
146
|
|
|
* Performs the search function calls. And wraps the result in a json-ld object. |
|
147
|
|
|
* @param Request $request |
|
148
|
|
|
*/ |
|
149
|
|
|
public function search($request) |
|
150
|
|
|
{ |
|
151
|
|
|
$maxhits = $request->getQueryParam('maxhits'); |
|
152
|
|
|
$offset = $request->getQueryParam('offset'); |
|
153
|
|
|
$term = $request->getQueryParam('query'); |
|
154
|
|
|
|
|
155
|
|
|
if (!$term) { |
|
156
|
|
|
return $this->returnError(400, "Bad Request", "query parameter missing"); |
|
157
|
|
|
} |
|
158
|
|
|
if ($maxhits && (!is_numeric($maxhits) || $maxhits <= 0)) { |
|
159
|
|
|
return $this->returnError(400, "Bad Request", "maxhits parameter is invalid"); |
|
160
|
|
|
} |
|
161
|
|
|
if ($offset && (!is_numeric($offset) || $offset < 0)) { |
|
162
|
|
|
return $this->returnError(400, "Bad Request", "offset parameter is invalid"); |
|
163
|
|
|
} |
|
164
|
|
|
|
|
165
|
|
|
$lang = $request->getQueryParam('lang'); # optional |
|
166
|
|
|
$labellang = $request->getQueryParam('labellang'); # optional |
|
167
|
|
|
|
|
168
|
|
|
$parameters = new ConceptSearchParameters($request, $this->model->getConfig(), true); |
|
169
|
|
|
|
|
170
|
|
|
$vocabs = $request->getQueryParam('vocab'); # optional |
|
171
|
|
|
// convert to vocids array to support multi-vocabulary search |
|
172
|
|
|
$vocids = ($vocabs !== null && $vocabs !== '') ? explode(' ', $vocabs) : array(); |
|
173
|
|
|
$vocabObjects = array(); |
|
174
|
|
|
foreach($vocids as $vocid) { |
|
175
|
|
|
$vocabObjects[] = $this->model->getVocabulary($vocid); |
|
176
|
|
|
} |
|
177
|
|
|
$parameters->setVocabularies($vocabObjects); |
|
178
|
|
|
|
|
179
|
|
|
$results = $this->model->searchConcepts($parameters); |
|
180
|
|
|
// before serializing to JSON, get rid of the Vocabulary object that came with each resource |
|
181
|
|
|
foreach ($results as &$res) { |
|
182
|
|
|
unset($res['voc']); |
|
183
|
|
|
} |
|
184
|
|
|
|
|
185
|
|
|
$ret = array( |
|
186
|
|
|
'@context' => array( |
|
187
|
|
|
'skos' => 'http://www.w3.org/2004/02/skos/core#', |
|
188
|
|
|
'onki' => 'http://schema.onki.fi/onki#', |
|
189
|
|
|
'uri' => '@id', |
|
190
|
|
|
'type' => '@type', |
|
191
|
|
|
'results' => array( |
|
192
|
|
|
'@id' => 'onki:results', |
|
193
|
|
|
'@container' => '@list', |
|
194
|
|
|
), |
|
195
|
|
|
'prefLabel' => 'skos:prefLabel', |
|
196
|
|
|
'altLabel' => 'skos:altLabel', |
|
197
|
|
|
'hiddenLabel' => 'skos:hiddenLabel', |
|
198
|
|
|
'broader' => 'skos:broader', |
|
199
|
|
|
), |
|
200
|
|
|
'uri' => '', |
|
201
|
|
|
'results' => $results, |
|
202
|
|
|
); |
|
203
|
|
|
|
|
204
|
|
|
if ($labellang) { |
|
205
|
|
|
$ret['@context']['@language'] = $labellang; |
|
206
|
|
|
} elseif ($lang) { |
|
207
|
|
|
$ret['@context']['@language'] = $lang; |
|
208
|
|
|
} |
|
209
|
|
|
|
|
210
|
|
|
return $this->returnJson($ret); |
|
211
|
|
|
} |
|
212
|
|
|
|
|
213
|
|
|
/** Vocabulary-specific methods **/ |
|
214
|
|
|
|
|
215
|
|
|
/** |
|
216
|
|
|
* Loads the vocabulary metadata. And wraps the result in a json-ld object. |
|
217
|
|
|
* @param Request $request |
|
218
|
|
|
*/ |
|
219
|
|
|
public function vocabularyInformation($request) |
|
220
|
|
|
{ |
|
221
|
|
|
$vocab = $request->getVocab(); |
|
222
|
|
|
|
|
223
|
|
|
/* encode the results in a JSON-LD compatible array */ |
|
224
|
|
|
$conceptschemes = array(); |
|
225
|
|
|
foreach ($vocab->getConceptSchemes() as $uri => $csdata) { |
|
226
|
|
|
$csdata['uri'] = $uri; |
|
227
|
|
|
$csdata['type'] = 'skos:ConceptScheme'; |
|
228
|
|
|
$conceptschemes[] = $csdata; |
|
229
|
|
|
} |
|
230
|
|
|
|
|
231
|
|
|
$ret = array( |
|
232
|
|
|
'@context' => array( |
|
233
|
|
|
'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#', |
|
234
|
|
|
'skos' => 'http://www.w3.org/2004/02/skos/core#', |
|
235
|
|
|
'onki' => 'http://schema.onki.fi/onki#', |
|
236
|
|
|
'dct' => 'http://purl.org/dc/terms/', |
|
237
|
|
|
'uri' => '@id', |
|
238
|
|
|
'type' => '@type', |
|
239
|
|
|
'title' => 'rdfs:label', |
|
240
|
|
|
'conceptschemes' => 'onki:hasConceptScheme', |
|
241
|
|
|
'id' => 'onki:vocabularyIdentifier', |
|
242
|
|
|
'defaultLanguage' => 'onki:defaultLanguage', |
|
243
|
|
|
'languages' => 'onki:language', |
|
244
|
|
|
'label' => 'rdfs:label', |
|
245
|
|
|
'prefLabel' => 'skos:prefLabel', |
|
246
|
|
|
'title' => 'dct:title', |
|
247
|
|
|
'@language' => $request->getLang(), |
|
248
|
|
|
), |
|
249
|
|
|
'uri' => '', |
|
250
|
|
|
'id' => $vocab->getId(), |
|
251
|
|
|
'title' => $vocab->getConfig()->getTitle($request->getLang()), |
|
252
|
|
|
'defaultLanguage' => $vocab->getConfig()->getDefaultLanguage(), |
|
253
|
|
|
'languages' => $vocab->getConfig()->getLanguages(), |
|
254
|
|
|
'conceptschemes' => $conceptschemes, |
|
255
|
|
|
); |
|
256
|
|
|
|
|
257
|
|
|
return $this->returnJson($ret); |
|
258
|
|
|
} |
|
259
|
|
|
|
|
260
|
|
|
/** |
|
261
|
|
|
* Loads the vocabulary metadata. And wraps the result in a json-ld object. |
|
262
|
|
|
* @param Request $request |
|
263
|
|
|
*/ |
|
264
|
|
|
public function vocabularyStatistics($request) |
|
265
|
|
|
{ |
|
266
|
|
|
$this->setLanguageProperties($request->getLang()); |
|
267
|
|
|
$arrayClass = $request->getVocab()->getConfig()->getArrayClassURI(); |
|
268
|
|
|
$groupClass = $request->getVocab()->getConfig()->getGroupClassURI(); |
|
269
|
|
|
$vocab_stats = $request->getVocab()->getStatistics($request->getQueryParam('lang'), $arrayClass, $groupClass); |
|
270
|
|
|
$types = array('http://www.w3.org/2004/02/skos/core#Concept', 'http://www.w3.org/2004/02/skos/core#Collection', $arrayClass, $groupClass); |
|
271
|
|
|
$subTypes = array(); |
|
272
|
|
|
foreach ($vocab_stats as $subtype) { |
|
273
|
|
|
if (!in_array($subtype['type'], $types)) { |
|
274
|
|
|
$subTypes[] = $subtype; |
|
275
|
|
|
} |
|
276
|
|
|
} |
|
277
|
|
|
|
|
278
|
|
|
/* encode the results in a JSON-LD compatible array */ |
|
279
|
|
|
$ret = array( |
|
280
|
|
|
'@context' => array( |
|
281
|
|
|
'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#', |
|
282
|
|
|
'skos' => 'http://www.w3.org/2004/02/skos/core#', |
|
283
|
|
|
'void' => 'http://rdfs.org/ns/void#', |
|
284
|
|
|
'onki' => 'http://schema.onki.fi/onki#', |
|
285
|
|
|
'uri' => '@id', |
|
286
|
|
|
'id' => 'onki:vocabularyIdentifier', |
|
287
|
|
|
'concepts' => 'void:classPartition', |
|
288
|
|
|
'label' => 'rdfs:label', |
|
289
|
|
|
'class' => array('@id' => 'void:class', '@type' => '@id'), |
|
290
|
|
|
'subTypes' => array('@id' => 'void:class', '@type' => '@id'), |
|
291
|
|
|
'count' => 'void:entities', |
|
292
|
|
|
'@language' => $request->getLang(), |
|
293
|
|
|
), |
|
294
|
|
|
'uri' => '', |
|
295
|
|
|
'id' => $request->getVocab()->getId(), |
|
296
|
|
|
'title' => $request->getVocab()->getConfig()->getTitle(), |
|
297
|
|
|
'concepts' => array( |
|
298
|
|
|
'class' => 'http://www.w3.org/2004/02/skos/core#Concept', |
|
299
|
|
|
'label' => gettext('skos:Concept'), |
|
300
|
|
|
'count' => $vocab_stats['http://www.w3.org/2004/02/skos/core#Concept']['count'], |
|
301
|
|
|
), |
|
302
|
|
|
'subTypes' => $subTypes, |
|
303
|
|
|
); |
|
304
|
|
|
|
|
305
|
|
|
if (isset($vocab_stats['http://www.w3.org/2004/02/skos/core#Collection'])) { |
|
306
|
|
|
$ret['conceptGroups'] = array( |
|
307
|
|
|
'class' => 'http://www.w3.org/2004/02/skos/core#Collection', |
|
308
|
|
|
'label' => gettext('skos:Collection'), |
|
309
|
|
|
'count' => $vocab_stats['http://www.w3.org/2004/02/skos/core#Collection']['count'], |
|
310
|
|
|
); |
|
311
|
|
|
} else if (isset($vocab_stats[$groupClass])) { |
|
312
|
|
|
$ret['conceptGroups'] = array( |
|
313
|
|
|
'class' => $groupClass, |
|
314
|
|
|
'label' => isset($vocab_stats[$groupClass]['label']) ? $vocab_stats[$groupClass]['label'] : gettext(EasyRdf_Namespace::shorten($groupClass)), |
|
315
|
|
|
'count' => $vocab_stats[$groupClass]['count'], |
|
316
|
|
|
); |
|
317
|
|
|
} else if (isset($vocab_stats[$arrayClass])) { |
|
318
|
|
|
$ret['arrays'] = array( |
|
319
|
|
|
'class' => $arrayClass, |
|
320
|
|
|
'label' => isset($vocab_stats[$arrayClass]['label']) ? $vocab_stats[$arrayClass]['label'] : gettext(EasyRdf_Namespace::shorten($arrayClass)), |
|
321
|
|
|
'count' => $vocab_stats[$arrayClass]['count'], |
|
322
|
|
|
); |
|
323
|
|
|
} |
|
324
|
|
|
|
|
325
|
|
|
return $this->returnJson($ret); |
|
326
|
|
|
} |
|
327
|
|
|
|
|
328
|
|
|
/** |
|
329
|
|
|
* Loads the vocabulary metadata. And wraps the result in a json-ld object. |
|
330
|
|
|
* @param Request $request |
|
331
|
|
|
*/ |
|
332
|
|
|
public function labelStatistics($request) |
|
333
|
|
|
{ |
|
334
|
|
|
$lang = $request->getLang(); |
|
335
|
|
|
$this->setLanguageProperties($request->getLang()); |
|
336
|
|
|
$vocab_stats = $request->getVocab()->getLabelStatistics(); |
|
337
|
|
|
|
|
338
|
|
|
/* encode the results in a JSON-LD compatible array */ |
|
339
|
|
|
$counts = array(); |
|
340
|
|
|
foreach ($vocab_stats['terms'] as $proplang => $properties) { |
|
341
|
|
|
$langdata = array('language' => $proplang); |
|
342
|
|
|
if ($lang) { |
|
343
|
|
|
$langdata['literal'] = Punic\Language::getName($proplang, $lang); |
|
344
|
|
|
} |
|
345
|
|
|
|
|
346
|
|
|
$langdata['properties'] = array(); |
|
347
|
|
|
foreach ($properties as $prop => $value) { |
|
348
|
|
|
$langdata['properties'][] = array('property' => $prop, 'labels' => $value); |
|
349
|
|
|
} |
|
350
|
|
|
$counts[] = $langdata; |
|
351
|
|
|
} |
|
352
|
|
|
|
|
353
|
|
|
$ret = array( |
|
354
|
|
|
'@context' => array( |
|
355
|
|
|
'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#', |
|
356
|
|
|
'skos' => 'http://www.w3.org/2004/02/skos/core#', |
|
357
|
|
|
'void' => 'http://rdfs.org/ns/void#', |
|
358
|
|
|
'void-ext' => 'http://ldf.fi/void-ext#', |
|
359
|
|
|
'onki' => 'http://schema.onki.fi/onki#', |
|
360
|
|
|
'uri' => '@id', |
|
361
|
|
|
'id' => 'onki:vocabularyIdentifier', |
|
362
|
|
|
'languages' => 'void-ext:languagePartition', |
|
363
|
|
|
'language' => 'void-ext:language', |
|
364
|
|
|
'properties' => 'void:propertyPartition', |
|
365
|
|
|
'labels' => 'void:triples', |
|
366
|
|
|
), |
|
367
|
|
|
'uri' => '', |
|
368
|
|
|
'id' => $request->getVocab()->getId(), |
|
369
|
|
|
'title' => $request->getVocab()->getConfig()->getTitle($lang), |
|
370
|
|
|
'languages' => $counts, |
|
371
|
|
|
); |
|
372
|
|
|
|
|
373
|
|
|
if ($lang) { |
|
374
|
|
|
$ret['@context']['literal'] = array('@id' => 'rdfs:label', '@language' => $lang); |
|
375
|
|
|
} |
|
376
|
|
|
|
|
377
|
|
|
return $this->returnJson($ret); |
|
378
|
|
|
} |
|
379
|
|
|
|
|
380
|
|
|
/** |
|
381
|
|
|
* Loads the vocabulary type metadata. And wraps the result in a json-ld object. |
|
382
|
|
|
* @param Request $request |
|
383
|
|
|
*/ |
|
384
|
|
|
public function types($request) |
|
385
|
|
|
{ |
|
386
|
|
|
$this->setLanguageProperties($request->getLang()); |
|
387
|
|
|
$vocid = $request->getVocab() ? $request->getVocab()->getId() : null; |
|
388
|
|
|
$queriedtypes = $this->model->getTypes($vocid, $request->getLang()); |
|
389
|
|
|
|
|
390
|
|
|
$types = array(); |
|
391
|
|
|
|
|
392
|
|
|
/* encode the results in a JSON-LD compatible array */ |
|
393
|
|
|
foreach ($queriedtypes as $uri => $typedata) { |
|
394
|
|
|
$type = array_merge(array('uri' => $uri), $typedata); |
|
395
|
|
|
$types[] = $type; |
|
396
|
|
|
} |
|
397
|
|
|
|
|
398
|
|
|
$ret = array_merge_recursive($this->context, array( |
|
399
|
|
|
'@context' => array('rdfs' => 'http://www.w3.org/2000/01/rdf-schema#', 'onki' => 'http://schema.onki.fi/onki#', 'label' => 'rdfs:label', 'superclass' => array('@id' => 'rdfs:subClassOf', '@type' => '@id'), 'types' => 'onki:hasType', '@language' => $request->getLang()), |
|
400
|
|
|
'uri' => '', |
|
401
|
|
|
'types' => $types) |
|
402
|
|
|
); |
|
403
|
|
|
|
|
404
|
|
|
return $this->returnJson($ret); |
|
405
|
|
|
} |
|
406
|
|
|
|
|
407
|
|
|
/** |
|
408
|
|
|
* Used for finding terms by their exact prefLabel. Wraps the result in a json-ld object. |
|
409
|
|
|
* @param Request $request |
|
410
|
|
|
*/ |
|
411
|
|
|
public function lookup($request) |
|
412
|
|
|
{ |
|
413
|
|
|
$label = $request->getQueryParam('label'); |
|
414
|
|
|
if (!$label) { |
|
415
|
|
|
return $this->returnError(400, "Bad Request", "label parameter missing"); |
|
416
|
|
|
} |
|
417
|
|
|
|
|
418
|
|
|
$lang = $request->getQueryParam('lang'); |
|
419
|
|
|
$vocab = $request->getVocab(); |
|
|
|
|
|
|
420
|
|
|
|
|
421
|
|
|
$parameters = new ConceptSearchParameters($request, $this->model->getConfig(), true); |
|
422
|
|
|
|
|
423
|
|
|
$results = $this->model->searchConcepts($parameters); |
|
424
|
|
|
|
|
425
|
|
|
$hits = array(); |
|
426
|
|
|
// case 1: exact match on preferred label |
|
427
|
|
|
foreach ($results as $res) { |
|
428
|
|
|
if ($res['prefLabel'] == $label) { |
|
429
|
|
|
$hits[] = $res; |
|
430
|
|
|
} |
|
431
|
|
|
} |
|
432
|
|
|
|
|
433
|
|
|
// case 2: case-insensitive match on preferred label |
|
434
|
|
|
if (sizeof($hits) == 0) { // not yet found |
|
435
|
|
|
foreach ($results as $res) { |
|
436
|
|
|
if (strtolower($res['prefLabel']) == strtolower($label)) { |
|
437
|
|
|
$hits[] = $res; |
|
438
|
|
|
} |
|
439
|
|
|
} |
|
440
|
|
|
|
|
441
|
|
|
} |
|
442
|
|
|
|
|
443
|
|
|
// case 3: exact match on alternate label |
|
444
|
|
View Code Duplication |
if (sizeof($hits) == 0) { // not yet found |
|
|
|
|
|
|
445
|
|
|
foreach ($results as $res) { |
|
446
|
|
|
if (isset($res['altLabel']) && $res['altLabel'] == $label) { |
|
447
|
|
|
$hits[] = $res; |
|
448
|
|
|
} |
|
449
|
|
|
} |
|
450
|
|
|
|
|
451
|
|
|
} |
|
452
|
|
|
|
|
453
|
|
|
// case 4: case-insensitive match on alternate label |
|
454
|
|
View Code Duplication |
if (sizeof($hits) == 0) { // not yet found |
|
|
|
|
|
|
455
|
|
|
foreach ($results as $res) { |
|
456
|
|
|
if (isset($res['altLabel']) && strtolower($res['altLabel']) == strtolower($label)) { |
|
457
|
|
|
$hits[] = $res; |
|
458
|
|
|
} |
|
459
|
|
|
} |
|
460
|
|
|
|
|
461
|
|
|
} |
|
462
|
|
|
|
|
463
|
|
|
if (sizeof($hits) == 0) { |
|
464
|
|
|
// no matches found |
|
465
|
|
|
return $this->returnError(404, 'Not Found', "Could not find label '$label'"); |
|
466
|
|
|
} |
|
467
|
|
|
|
|
468
|
|
|
// did find some matches! |
|
469
|
|
|
// get rid of Vocabulary objects |
|
470
|
|
|
foreach ($hits as &$res) { |
|
471
|
|
|
unset($res['voc']); |
|
472
|
|
|
} |
|
473
|
|
|
|
|
474
|
|
|
$ret = array_merge_recursive($this->context, array( |
|
475
|
|
|
'@context' => array('onki' => 'http://schema.onki.fi/onki#', 'results' => array('@id' => 'onki:results'), 'prefLabel' => 'skos:prefLabel', 'altLabel' => 'skos:altLabel', 'hiddenLabel' => 'skos:hiddenLabel'), |
|
476
|
|
|
'result' => $hits) |
|
477
|
|
|
); |
|
478
|
|
|
|
|
479
|
|
|
if ($lang) { |
|
480
|
|
|
$ret['@context']['@language'] = $lang; |
|
481
|
|
|
} |
|
482
|
|
|
|
|
483
|
|
|
return $this->returnJson($ret); |
|
484
|
|
|
} |
|
485
|
|
|
|
|
486
|
|
|
/** |
|
487
|
|
|
* Queries the top concepts of a vocabulary and wraps the results in a json-ld object. |
|
488
|
|
|
* @param Request $request |
|
489
|
|
|
* @return object json-ld object |
|
490
|
|
|
*/ |
|
491
|
|
|
public function topConcepts($request) |
|
492
|
|
|
{ |
|
493
|
|
|
$vocab = $request->getVocab(); |
|
494
|
|
|
$scheme = $request->getQueryParam('scheme'); |
|
495
|
|
|
if (!$scheme) { |
|
496
|
|
|
$scheme = $vocab->getConfig()->showConceptSchemesInHierarchy() ? array_keys($vocab->getConceptSchemes()) : $vocab->getDefaultConceptScheme(); |
|
497
|
|
|
} |
|
498
|
|
|
|
|
499
|
|
|
/* encode the results in a JSON-LD compatible array */ |
|
500
|
|
|
$topconcepts = $vocab->getTopConcepts($scheme, $request->getLang()); |
|
501
|
|
|
|
|
502
|
|
|
$ret = array_merge_recursive($this->context, array( |
|
503
|
|
|
'@context' => array('onki' => 'http://schema.onki.fi/onki#', 'topconcepts' => 'skos:hasTopConcept', 'notation' => 'skos:notation', 'label' => 'skos:prefLabel', '@language' => $request->getLang()), |
|
504
|
|
|
'uri' => $scheme, |
|
505
|
|
|
'topconcepts' => $topconcepts) |
|
506
|
|
|
); |
|
507
|
|
|
|
|
508
|
|
|
return $this->returnJson($ret); |
|
509
|
|
|
} |
|
510
|
|
|
|
|
511
|
|
|
/** |
|
512
|
|
|
* Download a concept as json-ld or redirect to download the whole vocabulary. |
|
513
|
|
|
* @param Request $request |
|
514
|
|
|
* @return object json-ld formatted concept. |
|
515
|
|
|
*/ |
|
516
|
|
|
public function data($request) |
|
517
|
|
|
{ |
|
518
|
|
|
$vocab = $request->getVocab(); |
|
519
|
|
|
$format = $request->getQueryParam('format'); |
|
520
|
|
|
|
|
521
|
|
|
if ($request->getUri()) { |
|
522
|
|
|
$uri = $request->getUri(); |
|
523
|
|
|
} else if ($vocab !== null) { // whole vocabulary - redirect to download URL |
|
524
|
|
|
$urls = $vocab->getConfig()->getDataURLs(); |
|
525
|
|
|
if (sizeof($urls) == 0) { |
|
526
|
|
|
return $this->returnError('404', 'Not Found', "No download source URL known for vocabulary $vocab"); |
|
527
|
|
|
} |
|
528
|
|
|
|
|
529
|
|
|
$format = $this->negotiateFormat(array_keys($urls), $request->getServerConstant('HTTP_ACCEPT'), $format); |
|
530
|
|
|
if (!$format) { |
|
531
|
|
|
return $this->returnError(406, 'Not Acceptable', "Unsupported format. Supported MIME types are: " . implode(' ', array_keys($urls))); |
|
532
|
|
|
} |
|
533
|
|
|
|
|
534
|
|
|
header("Location: " . $urls[$format]); |
|
535
|
|
|
return; |
|
536
|
|
|
} else { |
|
537
|
|
|
return $this->returnError(400, 'Bad Request', "uri parameter missing"); |
|
538
|
|
|
} |
|
539
|
|
|
|
|
540
|
|
|
$format = $this->negotiateFormat(explode(' ', self::$SUPPORTED_MIME_TYPES), $request->getServerConstant('HTTP_ACCEPT'), $format); |
|
541
|
|
|
if (!$format) { |
|
542
|
|
|
return $this->returnError(406, 'Not Acceptable', "Unsupported format. Supported MIME types are: " . self::$SUPPORTED_MIME_TYPES); |
|
543
|
|
|
} |
|
544
|
|
|
|
|
545
|
|
|
$vocid = $vocab ? $vocab->getId() : null; |
|
546
|
|
|
$results = $this->model->getRDF($vocid, $uri, $format); |
|
547
|
|
|
|
|
548
|
|
|
if ($format == 'application/ld+json' || $format == 'application/json') { |
|
549
|
|
|
// further compact JSON-LD document using a context |
|
550
|
|
|
$context = array( |
|
551
|
|
|
'skos' => 'http://www.w3.org/2004/02/skos/core#', |
|
552
|
|
|
'isothes' => 'http://purl.org/iso25964/skos-thes#', |
|
553
|
|
|
'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#', |
|
554
|
|
|
'owl' => 'http://www.w3.org/2002/07/owl#', |
|
555
|
|
|
'dct' => 'http://purl.org/dc/terms/', |
|
556
|
|
|
'dc11' => 'http://purl.org/dc/elements/1.1/', |
|
557
|
|
|
'uri' => '@id', |
|
558
|
|
|
'type' => '@type', |
|
559
|
|
|
'lang' => '@language', |
|
560
|
|
|
'value' => '@value', |
|
561
|
|
|
'graph' => '@graph', |
|
562
|
|
|
'label' => 'rdfs:label', |
|
563
|
|
|
'prefLabel' => 'skos:prefLabel', |
|
564
|
|
|
'altLabel' => 'skos:altLabel', |
|
565
|
|
|
'hiddenLabel' => 'skos:hiddenLabel', |
|
566
|
|
|
'broader' => 'skos:broader', |
|
567
|
|
|
'narrower' => 'skos:narrower', |
|
568
|
|
|
'related' => 'skos:related', |
|
569
|
|
|
'inScheme' => 'skos:inScheme', |
|
570
|
|
|
); |
|
571
|
|
|
$compact_jsonld = \ML\JsonLD\JsonLD::compact($results, json_encode($context)); |
|
572
|
|
|
$results = \ML\JsonLD\JsonLD::toString($compact_jsonld); |
|
573
|
|
|
} |
|
574
|
|
|
|
|
575
|
|
|
header("Content-type: $format; charset=utf-8"); |
|
576
|
|
|
echo $results; |
|
577
|
|
|
} |
|
578
|
|
|
|
|
579
|
|
|
/** |
|
580
|
|
|
* Used for querying labels for a uri. |
|
581
|
|
|
* @param Request $request |
|
582
|
|
|
* @return object json-ld wrapped labels. |
|
583
|
|
|
*/ |
|
584
|
|
|
public function label($request) |
|
585
|
|
|
{ |
|
586
|
|
|
if (!$request->getUri()) { |
|
587
|
|
|
return $this->returnError(400, "Bad Request", "uri parameter missing"); |
|
588
|
|
|
} |
|
589
|
|
|
|
|
590
|
|
|
$results = $request->getVocab()->getConceptLabel($request->getUri(), $request->getLang()); |
|
591
|
|
|
if ($results === null) { |
|
592
|
|
|
return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>"); |
|
593
|
|
|
} |
|
594
|
|
|
|
|
595
|
|
|
$ret = array_merge_recursive($this->context, array( |
|
596
|
|
|
'@context' => array('prefLabel' => 'skos:prefLabel', '@language' => $request->getLang()), |
|
597
|
|
|
'uri' => $request->getUri()) |
|
598
|
|
|
); |
|
599
|
|
|
|
|
600
|
|
|
if (isset($results[$request->getLang()])) { |
|
601
|
|
|
$ret['prefLabel'] = $results[$request->getLang()]->getValue(); |
|
602
|
|
|
} |
|
603
|
|
|
|
|
604
|
|
|
return $this->returnJson($ret); |
|
605
|
|
|
} |
|
606
|
|
|
|
|
607
|
|
|
/** |
|
608
|
|
|
* Used for querying broader relations for a concept. |
|
609
|
|
|
* @param Request $request |
|
610
|
|
|
* @return object json-ld wrapped broader concept uris and labels. |
|
611
|
|
|
*/ |
|
612
|
|
View Code Duplication |
public function broader($request) |
|
|
|
|
|
|
613
|
|
|
{ |
|
614
|
|
|
$results = array(); |
|
615
|
|
|
$broaders = $request->getVocab()->getConceptBroaders($request->getUri(), $request->getLang()); |
|
616
|
|
|
if ($broaders === null) { |
|
617
|
|
|
return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>"); |
|
618
|
|
|
} |
|
619
|
|
|
|
|
620
|
|
|
foreach ($broaders as $object => $vals) { |
|
621
|
|
|
$results[] = array('uri' => $object, 'prefLabel' => $vals['label']); |
|
622
|
|
|
} |
|
623
|
|
|
|
|
624
|
|
|
$ret = array_merge_recursive($this->context, array( |
|
625
|
|
|
'@context' => array('prefLabel' => 'skos:prefLabel', 'broader' => 'skos:broader', '@language' => $request->getLang()), |
|
626
|
|
|
'uri' => $request->getUri(), |
|
627
|
|
|
'broader' => $results) |
|
628
|
|
|
); |
|
629
|
|
|
|
|
630
|
|
|
return $this->returnJson($ret); |
|
631
|
|
|
} |
|
632
|
|
|
|
|
633
|
|
|
/** |
|
634
|
|
|
* Used for querying broader transitive relations for a concept. |
|
635
|
|
|
* @param Request $request |
|
636
|
|
|
* @return object json-ld wrapped broader transitive concept uris and labels. |
|
637
|
|
|
*/ |
|
638
|
|
View Code Duplication |
public function broaderTransitive($request) |
|
|
|
|
|
|
639
|
|
|
{ |
|
640
|
|
|
$results = array(); |
|
641
|
|
|
$broaders = $request->getVocab()->getConceptTransitiveBroaders($request->getUri(), $this->parseLimit(), false, $request->getLang()); |
|
642
|
|
|
if (empty($broaders)) { |
|
643
|
|
|
return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>"); |
|
644
|
|
|
} |
|
645
|
|
|
|
|
646
|
|
|
foreach ($broaders as $buri => $vals) { |
|
647
|
|
|
$result = array('uri' => $buri, 'prefLabel' => $vals['label']); |
|
648
|
|
|
if (isset($vals['direct'])) { |
|
649
|
|
|
$result['broader'] = $vals['direct']; |
|
650
|
|
|
} |
|
651
|
|
|
$results[$buri] = $result; |
|
652
|
|
|
} |
|
653
|
|
|
|
|
654
|
|
|
$ret = array_merge_recursive($this->context, array( |
|
655
|
|
|
'@context' => array('prefLabel' => 'skos:prefLabel', 'broader' => array('@id' => 'skos:broader', '@type' => '@id'), 'broaderTransitive' => array('@id' => 'skos:broaderTransitive', '@container' => '@index'), '@language' => $request->getLang()), |
|
656
|
|
|
'uri' => $request->getUri(), |
|
657
|
|
|
'broaderTransitive' => $results) |
|
658
|
|
|
); |
|
659
|
|
|
|
|
660
|
|
|
return $this->returnJson($ret); |
|
661
|
|
|
} |
|
662
|
|
|
|
|
663
|
|
|
/** |
|
664
|
|
|
* Used for querying narrower relations for a concept. |
|
665
|
|
|
* @param Request $request |
|
666
|
|
|
* @return object json-ld wrapped narrower concept uris and labels. |
|
667
|
|
|
*/ |
|
668
|
|
View Code Duplication |
public function narrower($request) |
|
|
|
|
|
|
669
|
|
|
{ |
|
670
|
|
|
$results = array(); |
|
671
|
|
|
$narrowers = $request->getVocab()->getConceptNarrowers($request->getUri(), $request->getLang()); |
|
672
|
|
|
if ($narrowers === null) { |
|
673
|
|
|
return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>"); |
|
674
|
|
|
} |
|
675
|
|
|
|
|
676
|
|
|
foreach ($narrowers as $object => $vals) { |
|
677
|
|
|
$results[] = array('uri' => $object, 'prefLabel' => $vals['label']); |
|
678
|
|
|
} |
|
679
|
|
|
|
|
680
|
|
|
$ret = array_merge_recursive($this->context, array( |
|
681
|
|
|
'@context' => array('prefLabel' => 'skos:prefLabel', 'narrower' => 'skos:narrower', '@language' => $request->getLang()), |
|
682
|
|
|
'uri' => $request->getUri(), |
|
683
|
|
|
'narrower' => $results) |
|
684
|
|
|
); |
|
685
|
|
|
|
|
686
|
|
|
return $this->returnJson($ret); |
|
687
|
|
|
} |
|
688
|
|
|
|
|
689
|
|
|
/** |
|
690
|
|
|
* Used for querying narrower transitive relations for a concept. |
|
691
|
|
|
* @param Request $request |
|
692
|
|
|
* @return object json-ld wrapped narrower transitive concept uris and labels. |
|
693
|
|
|
*/ |
|
694
|
|
View Code Duplication |
public function narrowerTransitive($request) |
|
|
|
|
|
|
695
|
|
|
{ |
|
696
|
|
|
$results = array(); |
|
697
|
|
|
$narrowers = $request->getVocab()->getConceptTransitiveNarrowers($request->getUri(), $this->parseLimit(), $request->getLang()); |
|
698
|
|
|
if (empty($narrowers)) { |
|
699
|
|
|
return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>"); |
|
700
|
|
|
} |
|
701
|
|
|
|
|
702
|
|
|
foreach ($narrowers as $nuri => $vals) { |
|
703
|
|
|
$result = array('uri' => $nuri, 'prefLabel' => $vals['label']); |
|
704
|
|
|
if (isset($vals['direct'])) { |
|
705
|
|
|
$result['narrower'] = $vals['direct']; |
|
706
|
|
|
} |
|
707
|
|
|
$results[$nuri] = $result; |
|
708
|
|
|
} |
|
709
|
|
|
|
|
710
|
|
|
$ret = array_merge_recursive($this->context, array( |
|
711
|
|
|
'@context' => array('prefLabel' => 'skos:prefLabel', 'narrower' => array('@id' => 'skos:narrower', '@type' => '@id'), 'narrowerTransitive' => array('@id' => 'skos:narrowerTransitive', '@container' => '@index'), '@language' => $request->getLang()), |
|
712
|
|
|
'uri' => $request->getUri(), |
|
713
|
|
|
'narrowerTransitive' => $results) |
|
714
|
|
|
); |
|
715
|
|
|
|
|
716
|
|
|
return $this->returnJson($ret); |
|
717
|
|
|
} |
|
718
|
|
|
|
|
719
|
|
|
/** |
|
720
|
|
|
* Used for querying broader transitive relations |
|
721
|
|
|
* and some narrowers for a concept in the hierarchy view. |
|
722
|
|
|
* @param Request $request |
|
723
|
|
|
* @return object json-ld wrapped hierarchical concept uris and labels. |
|
724
|
|
|
*/ |
|
725
|
|
|
public function hierarchy($request) |
|
726
|
|
|
{ |
|
727
|
|
|
$results = $request->getVocab()->getConceptHierarchy($request->getUri(), $request->getLang()); |
|
728
|
|
|
if (empty($results)) { |
|
729
|
|
|
return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>"); |
|
730
|
|
|
} |
|
731
|
|
|
|
|
732
|
|
|
if ($request->getVocab()->getConfig()->getShowHierarchy()) { |
|
733
|
|
|
$schemes = $request->getVocab()->getConceptSchemes($request->getLang()); |
|
734
|
|
|
foreach ($schemes as $scheme) { |
|
735
|
|
|
if (!isset($scheme['title']) && !isset($scheme['label']) && !isset($scheme['prefLabel'])) { |
|
736
|
|
|
unset($schemes[array_search($scheme, $schemes)]); |
|
737
|
|
|
} |
|
738
|
|
|
|
|
739
|
|
|
} |
|
740
|
|
|
|
|
741
|
|
|
/* encode the results in a JSON-LD compatible array */ |
|
742
|
|
|
$topconcepts = $request->getVocab()->getTopConcepts(array_keys($schemes), $request->getLang()); |
|
743
|
|
|
foreach ($topconcepts as $top) { |
|
744
|
|
|
if (!isset($results[$top['uri']])) { |
|
745
|
|
|
$results[$top['uri']] = array('uri' => $top['uri'], 'top' => $top['topConceptOf'], 'prefLabel' => $top['label'], 'hasChildren' => $top['hasChildren']); |
|
746
|
|
|
if (isset($top['notation'])) { |
|
747
|
|
|
$results[$top['uri']]['notation'] = $top['notation']; |
|
748
|
|
|
} |
|
749
|
|
|
|
|
750
|
|
|
} |
|
751
|
|
|
} |
|
752
|
|
|
} |
|
753
|
|
|
|
|
754
|
|
|
$ret = array_merge_recursive($this->context, array( |
|
755
|
|
|
'@context' => array('onki' => 'http://schema.onki.fi/onki#', 'prefLabel' => 'skos:prefLabel', 'notation' => 'skos:notation', 'narrower' => array('@id' => 'skos:narrower', '@type' => '@id'), 'broader' => array('@id' => 'skos:broader', '@type' => '@id'), 'broaderTransitive' => array('@id' => 'skos:broaderTransitive', '@container' => '@index'), 'top' => array('@id' => 'skos:topConceptOf', '@type' => '@id'), 'hasChildren' => 'onki:hasChildren', '@language' => $request->getLang()), |
|
756
|
|
|
'uri' => $request->getUri(), |
|
757
|
|
|
'broaderTransitive' => $results) |
|
758
|
|
|
); |
|
759
|
|
|
|
|
760
|
|
|
return $this->returnJson($ret); |
|
761
|
|
|
} |
|
762
|
|
|
|
|
763
|
|
|
/** |
|
764
|
|
|
* Used for querying group hierarchy for the sidebar group view. |
|
765
|
|
|
* @param Request $request |
|
766
|
|
|
* @return object json-ld wrapped hierarchical concept uris and labels. |
|
767
|
|
|
*/ |
|
768
|
|
|
public function groups($request) |
|
769
|
|
|
{ |
|
770
|
|
|
$results = $request->getVocab()->listConceptGroups($request->getLang()); |
|
771
|
|
|
|
|
772
|
|
|
$ret = array_merge_recursive($this->context, array( |
|
773
|
|
|
'@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()), |
|
774
|
|
|
'uri' => '', |
|
775
|
|
|
'groups' => $results) |
|
776
|
|
|
); |
|
777
|
|
|
|
|
778
|
|
|
return $this->returnJson($ret); |
|
779
|
|
|
} |
|
780
|
|
|
|
|
781
|
|
|
/** |
|
782
|
|
|
* Used for querying member relations for a group. |
|
783
|
|
|
* @param Request $request |
|
784
|
|
|
* @return object json-ld wrapped narrower concept uris and labels. |
|
785
|
|
|
*/ |
|
786
|
|
|
public function groupMembers($request) |
|
787
|
|
|
{ |
|
788
|
|
|
$children = $request->getVocab()->listConceptGroupContents($request->getUri(), $request->getLang()); |
|
789
|
|
|
if (empty($children)) { |
|
790
|
|
|
return $this->returnError('404', 'Not Found', "Could not find group <{$request->getUri()}>"); |
|
791
|
|
|
} |
|
792
|
|
|
|
|
793
|
|
|
$ret = array_merge_recursive($this->context, array( |
|
794
|
|
|
'@context' => array('prefLabel' => 'skos:prefLabel', 'members' => 'skos:member', '@language' => $request->getLang()), |
|
795
|
|
|
'uri' => $request->getUri(), |
|
796
|
|
|
'members' => $children) |
|
797
|
|
|
); |
|
798
|
|
|
|
|
799
|
|
|
return $this->returnJson($ret); |
|
800
|
|
|
} |
|
801
|
|
|
|
|
802
|
|
|
/** |
|
803
|
|
|
* Used for querying narrower relations for a concept in the hierarchy view. |
|
804
|
|
|
* @param Request $request |
|
805
|
|
|
* @return object json-ld wrapped narrower concept uris and labels. |
|
806
|
|
|
*/ |
|
807
|
|
|
public function children($request) |
|
808
|
|
|
{ |
|
809
|
|
|
$children = $request->getVocab()->getConceptChildren($request->getUri(), $request->getLang()); |
|
810
|
|
|
if ($children === null) { |
|
811
|
|
|
return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>"); |
|
812
|
|
|
} |
|
813
|
|
|
|
|
814
|
|
|
$ret = array_merge_recursive($this->context, array( |
|
815
|
|
|
'@context' => array('prefLabel' => 'skos:prefLabel', 'narrower' => 'skos:narrower', 'notation' => 'skos:notation', 'hasChildren' => 'onki:hasChildren', '@language' => $request->getLang()), |
|
816
|
|
|
'uri' => $request->getUri(), |
|
817
|
|
|
'narrower' => $children) |
|
818
|
|
|
); |
|
819
|
|
|
|
|
820
|
|
|
return $this->returnJson($ret); |
|
821
|
|
|
} |
|
822
|
|
|
|
|
823
|
|
|
/** |
|
824
|
|
|
* Used for querying narrower relations for a concept in the hierarchy view. |
|
825
|
|
|
* @param Request $request |
|
826
|
|
|
* @return object json-ld wrapped hierarchical concept uris and labels. |
|
827
|
|
|
*/ |
|
828
|
|
|
public function related($request) |
|
829
|
|
|
{ |
|
830
|
|
|
$results = array(); |
|
831
|
|
|
$related = $request->getVocab()->getConceptRelateds($request->getUri(), $request->getLang()); |
|
832
|
|
|
if ($related === null) { |
|
833
|
|
|
return $this->returnError('404', 'Not Found', "Could not find concept <{$request->getUri()}>"); |
|
834
|
|
|
} |
|
835
|
|
|
|
|
836
|
|
|
foreach ($related as $uri => $vals) { |
|
837
|
|
|
$results[] = array('uri' => $uri, 'prefLabel' => $vals['label']); |
|
838
|
|
|
} |
|
839
|
|
|
|
|
840
|
|
|
$ret = array_merge_recursive($this->context, array( |
|
841
|
|
|
'@context' => array('prefLabel' => 'skos:prefLabel', 'related' => 'skos:related', '@language' => $request->getLang()), |
|
842
|
|
|
'uri' => $request->getUri(), |
|
843
|
|
|
'related' => $results) |
|
844
|
|
|
); |
|
845
|
|
|
|
|
846
|
|
|
return $this->returnJson($ret); |
|
847
|
|
|
} |
|
848
|
|
|
} |
|
849
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.