Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SKOS relations to JSON-LD serialization #748

Merged
merged 4 commits into from
Apr 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 37 additions & 16 deletions controller/RestController.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,27 +112,43 @@ private function constructSearchParameters($request)
return $parameters;
}

private function transformSearchResults($request, $results)
private function transformSearchResults($request, $results, $parameters)
{
// before serializing to JSON, get rid of the Vocabulary object that came with each resource
foreach ($results as &$res) {
unset($res['voc']);
}
$ret = array(
'@context' => array(
'skos' => 'http://www.w3.org/2004/02/skos/core#',
'isothes' => 'http://purl.org/iso25964/skos-thes#',
'onki' => 'http://schema.onki.fi/onki#',
'uri' => '@id',
'type' => '@type',
'results' => array(
'@id' => 'onki:results',
'@container' => '@list',
),
'prefLabel' => 'skos:prefLabel',
'altLabel' => 'skos:altLabel',
'hiddenLabel' => 'skos:hiddenLabel',

$context = array(
'skos' => 'http://www.w3.org/2004/02/skos/core#',
'isothes' => 'http://purl.org/iso25964/skos-thes#',
'onki' => 'http://schema.onki.fi/onki#',
'uri' => '@id',
'type' => '@type',
'results' => array(
'@id' => 'onki:results',
'@container' => '@list',
),
'prefLabel' => 'skos:prefLabel',
'altLabel' => 'skos:altLabel',
'hiddenLabel' => 'skos:hiddenLabel',
);
foreach ($parameters->getAdditionalFields() as $field) {

// Quick-and-dirty compactification
$context[$field] = 'skos:' . $field;
foreach ($results as &$result) {
foreach ($result as $k => $v) {
if ($k == 'skos:' . $field) {
$result[$field] = $v;
unset($result['skos:' . $field]);
}
}
}
}

$ret = array(
'@context' => $context,
'uri' => '',
'results' => $results,
);
Expand Down Expand Up @@ -171,7 +187,7 @@ public function search($request)

$parameters = $this->constructSearchParameters($request);
$results = $this->model->searchConcepts($parameters);
$ret = $this->transformSearchResults($request, $results);
$ret = $this->transformSearchResults($request, $results, $parameters);

return $this->returnJson($ret);
}
Expand Down Expand Up @@ -561,6 +577,11 @@ private function returnDataResults($results, $format) {
'narrower' => 'skos:narrower',
'related' => 'skos:related',
'inScheme' => 'skos:inScheme',
'exactMatch' => 'skos:exactMatch',
'closeMatch' => 'skos:closeMatch',
'broadMatch' => 'skos:broadMatch',
'narrowMatch' => 'skos:narrowMatch',
'relatedMatch' => 'skos:relatedMatch',
);
$compactJsonLD = \ML\JsonLD\JsonLD::compact($results, json_encode($context));
$results = \ML\JsonLD\JsonLD::toString($compactJsonLD);
Expand Down
2 changes: 1 addition & 1 deletion model/ConceptSearchParameters.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ private function getQueryParam($name) {
}

private function getQueryParamArray($name) {
return $this->request->getQueryParam($name) ? explode(' ', urldecode($this->request->getQueryParam($name))) : null;
return $this->request->getQueryParam($name) ? explode(' ', urldecode($this->request->getQueryParam($name))) : [];
}

public function getGroupLimit()
Expand Down
55 changes: 51 additions & 4 deletions model/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,57 @@ class Request
private $uri;
private $letter;
private $model;
private $queryParams;
private $queryParamsPOST;
private $serverConstants;

/**
* Initializes the Request Object
*/
public function __construct($model)
{
$this->model = $model;

// Store GET parameters in a local array, so we can mock them in tests.
// We do not apply any filters at this point.
$this->queryParams = [];
foreach (filter_input_array(INPUT_GET) ?: [] as $key => $val) {
$this->queryParams[$key] = $val;
}

// Store POST parameters in a local array, so we can mock them in tests.
// We do not apply any filters at this point.
$this->queryParamsPOST = [];
foreach (filter_input_array(INPUT_POST) ?: [] as $key => $val) {
$this->queryParamsPOST[$key] = $val;
}

// Store SERVER parameters in a local array, so we can mock them in tests.
// We do not apply any filters at this point.
$this->serverConstants = [];
foreach (filter_input_array(INPUT_SERVER) ?: [] as $key => $val) {
$this->serverConstants[$key] = $val;
}
}

/**
* Set a GET query parameter to mock it in tests.
* @param string $paramName parameter name
* @param string $value parameter value
*/
public function setQueryParam($paramName, $value)
{
$this->queryParams[$paramName] = $value;
}

/**
* Set a SERVER constant to mock it in tests.
* @param string $paramName parameter name
* @param string $value parameter value
*/
public function setServerConstant($paramName, $value)
{
$this->serverConstants[$paramName] = $value;
}

/**
Expand All @@ -30,7 +74,8 @@ public function __construct($model)
*/
public function getQueryParam($paramName)
{
$val = filter_input(INPUT_GET, $paramName, FILTER_SANITIZE_STRING);
if (!isset($this->queryParams[$paramName])) return null;
$val = filter_var($this->queryParams[$paramName], FILTER_SANITIZE_STRING);
return ($val !== null ? str_replace('\\', '', $val) : null);
}

Expand All @@ -41,12 +86,13 @@ public function getQueryParam($paramName)
*/
public function getQueryParamRaw($paramName)
{
return filter_input(INPUT_GET, $paramName, FILTER_UNSAFE_RAW);
return isset($this->queryParams[$paramName]) ? $this->queryParams[$paramName] : null;
}

public function getQueryParamPOST($paramName)
{
return filter_input(INPUT_POST, $paramName, FILTER_SANITIZE_STRING);
if (!isset($this->queryParamsPOST[$paramName])) return null;
return filter_var($this->queryParamsPOST[$paramName], FILTER_SANITIZE_STRING);
}

public function getQueryParamBoolean($paramName, $default)
Expand All @@ -60,7 +106,8 @@ public function getQueryParamBoolean($paramName, $default)

public function getServerConstant($paramName)
{
return filter_input(INPUT_SERVER, $paramName, FILTER_SANITIZE_STRING);
if (!isset($this->serverConstants[$paramName])) return null;
return filter_var($this->serverConstants[$paramName], FILTER_SANITIZE_STRING);
}

public function getLang()
Expand Down
2 changes: 1 addition & 1 deletion tests/ConceptSearchParametersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public function testGetArrayClass() {
*/
public function testGetSchemeLimit() {
$params = new ConceptSearchParameters($this->request, new GlobalConfig('/../tests/testconfig.inc'));
$this->assertEquals(null, $params->getSchemeLimit());
$this->assertEquals([], $params->getSchemeLimit());
$this->request->method('getQueryParam')->will($this->returnValue('http://www.skosmos.skos/test/ http://www.skosmos.skos/date/'));
$this->assertEquals(array(0 => 'http://www.skosmos.skos/test/', 1 => 'http://www.skosmos.skos/date/'), $params->getSchemeLimit());
}
Expand Down
64 changes: 64 additions & 0 deletions tests/RestControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

require_once('model/GlobalConfig.php');
require_once('model/Model.php');
require_once('model/Request.php');
require_once('controller/RestController.php');

class RestControllerTest extends \PHPUnit\Framework\TestCase
{
protected function setUp() {
require_once 'testconfig.inc';
putenv("LC_ALL=en_GB.utf8");
setlocale(LC_ALL, 'en_GB.utf8');
bindtextdomain('skosmos', 'resource/translations');
bind_textdomain_codeset('skosmos', 'UTF-8');
textdomain('skosmos');

$this->model = new Model(new GlobalConfig('/../tests/testconfig.inc'));
$this->controller = new RestController($this->model);
}

/**
* @covers RestController::data
*/
public function testDataAsJson() {
$request = new Request($this->model);
$request->setQueryParam('format', 'application/json');
$request->setURI('http://www.skosmos.skos/test/ta117');
$this->controller->data($request);

$out = $this->getActualOutput();

$this->assertJsonStringEqualsJsonString('{"@context":{"skos":"http://www.w3.org/2004/02/skos/core#","isothes":"http://purl.org/iso25964/skos-thes#","rdfs":"http://www.w3.org/2000/01/rdf-schema#","owl":"http://www.w3.org/2002/07/owl#","dct":"http://purl.org/dc/terms/","dc11":"http://purl.org/dc/elements/1.1/","uri":"@id","type":"@type","lang":"@language","value":"@value","graph":"@graph","label":"rdfs:label","prefLabel":"skos:prefLabel","altLabel":"skos:altLabel","hiddenLabel":"skos:hiddenLabel","broader":"skos:broader","narrower":"skos:narrower","related":"skos:related","inScheme":"skos:inScheme","exactMatch":"skos:exactMatch","closeMatch":"skos:closeMatch","broadMatch":"skos:broadMatch","narrowMatch":"skos:narrowMatch","relatedMatch":"skos:relatedMatch"},"graph":[{"uri":"http://www.skosmos.skos/test-meta/TestClass","type":"owl:Class","label":{"lang":"en","value":"Test class"}},{"uri":"http://www.skosmos.skos/test/conceptscheme","type":"skos:ConceptScheme","label":{"lang":"en","value":"Test conceptscheme"}},{"uri":"http://www.skosmos.skos/test/ta1","type":["http://www.skosmos.skos/test-meta/TestClass","skos:Concept"],"narrower":{"uri":"http://www.skosmos.skos/test/ta117"},"prefLabel":{"lang":"en","value":"Fish"}},{"uri":"http://www.skosmos.skos/test/ta115","type":["http://www.skosmos.skos/test-meta/TestClass","skos:Concept"],"prefLabel":{"lang":"en","value":"Eel"}},{"uri":"http://www.skosmos.skos/test/ta117","type":["http://www.skosmos.skos/test-meta/TestClass","skos:Concept"],"broader":{"uri":"http://www.skosmos.skos/test/ta1"},"inScheme":{"uri":"http://www.skosmos.skos/test/conceptscheme"},"prefLabel":{"lang":"en","value":"3D Bass"},"relatedMatch":{"uri":"http://www.skosmos.skos/test/ta115"}},{"uri":"skos:broader","label":{"lang":"en","value":"has broader"}},{"uri":"skos:prefLabel","label":{"lang":"en","value":"preferred label"}}]}', $out);
}

/**
* @covers RestController::search
*/
public function testSearchJsonLd() {
$request = new Request($this->model);
$request->setQueryParam('format', 'application/json');
$request->setQueryParam('query', '*bass');
$this->controller->search($request);

$out = $this->getActualOutput();

$this->assertJsonStringEqualsJsonString('{"@context":{"skos":"http:\/\/www.w3.org\/2004\/02\/skos\/core#","isothes":"http:\/\/purl.org\/iso25964\/skos-thes#","onki":"http:\/\/schema.onki.fi\/onki#","uri":"@id","type":"@type","results":{"@id":"onki:results","@container":"@list"},"prefLabel":"skos:prefLabel","altLabel":"skos:altLabel","hiddenLabel":"skos:hiddenLabel"},"uri":"","results":[{"uri":"http:\/\/www.skosmos.skos\/test\/ta117","type":["skos:Concept","meta:TestClass"],"prefLabel":"3D Bass","lang":"en","vocab":"test"},{"uri":"http:\/\/www.skosmos.skos\/test\/ta116","type":["skos:Concept","meta:TestClass"],"prefLabel":"Bass","lang":"en","vocab":"test"},{"uri":"http:\/\/www.skosmos.skos\/test\/ta122","type":["skos:Concept","meta:TestClass"],"prefLabel":"Black sea bass","lang":"en","vocab":"test"}]}', $out);
}

/**
* @covers RestController::search
*/
public function testSearchJsonLdWithAdditionalFields() {
$request = new Request($this->model);
$request->setQueryParam('format', 'application/json');
$request->setQueryParam('query', '*bass');
$request->setQueryParam('fields', 'broader relatedMatch');
$this->controller->search($request);

$out = $this->getActualOutput();

$this->assertJsonStringEqualsJsonString('{"@context":{"skos":"http:\/\/www.w3.org\/2004\/02\/skos\/core#","isothes":"http:\/\/purl.org\/iso25964\/skos-thes#","onki":"http:\/\/schema.onki.fi\/onki#","uri":"@id","type":"@type","results":{"@id":"onki:results","@container":"@list"},"prefLabel":"skos:prefLabel","altLabel":"skos:altLabel","hiddenLabel":"skos:hiddenLabel","broader":"skos:broader","relatedMatch":"skos:relatedMatch"},"uri":"","results":[{"uri":"http:\/\/www.skosmos.skos\/test\/ta117","type":["skos:Concept","meta:TestClass"],"broader":[{"uri":"http:\/\/www.skosmos.skos\/test\/ta1"}],"relatedMatch":[{"uri":"http:\/\/www.skosmos.skos\/test\/ta115"}],"prefLabel":"3D Bass","lang":"en","vocab":"test"},{"uri":"http:\/\/www.skosmos.skos\/test\/ta116","type":["skos:Concept","meta:TestClass"],"broader":[{"uri":"http:\/\/www.skosmos.skos\/test\/ta1"}],"prefLabel":"Bass","lang":"en","vocab":"test"},{"uri":"http:\/\/www.skosmos.skos\/test\/ta122","type":["skos:Concept","meta:TestClass"],"broader":[{"uri":"http:\/\/www.skosmos.skos\/test\/ta116"}],"prefLabel":"Black sea bass","lang":"en","vocab":"test"}]}', $out);
}
}
1 change: 1 addition & 0 deletions tests/test-vocab-data/test.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ test:ta116 a skos:Concept, meta:TestClass ;
test:ta117 a skos:Concept, meta:TestClass ;
skos:broader test:ta1 ;
skos:inScheme test:conceptscheme ;
skos:relatedMatch test:ta115 ;
skos:prefLabel "3D Bass"@en .

test:ta118 a skos:Concept, meta:TestClass ;
Expand Down