Commit 8884e080 authored by root's avatar root
Browse files

Added IIIF Viewer Support

parent 9ebd3802
......@@ -5,14 +5,11 @@ namespace StableIdentifier;
use StableIdentifier\Config;
use StableIdentifier\Database;
class BarcodeUtil {
class DatabaseUtil {
private $db = null;
private $querytemplate = null;
function __construct(){
$this->db = new Database();
$this->querytemplate_one = Config::get('database')['query_one'];
$this->querytemplate_all = Config::get('database')['query_all'];
}
function __destruct(){
......@@ -24,12 +21,12 @@ class BarcodeUtil {
}
function getSpecimen($barcode){
$specimens = ($this->isValid($barcode)) ? $this->db->query($this->querytemplate_one, [$barcode]) : null;
$specimens = ($this->isValid($barcode)) ? $this->db->query(Config::get('database')['query_rdf_one'], [$barcode]) : null;
return (isset($specimens)) ? $specimens[0] : null;
}
function getAllSpecimen(){
return $this->db->query($this->querytemplate_all);
return $this->db->query(Config::get('database')['query_rdf_all']);
}
function getAllSpecimenEscaped(){
......@@ -44,11 +41,6 @@ class BarcodeUtil {
return (isset($specimen)) ? $this->escape($specimen) : null;
}
function isInDB($barcode) {
$result = $this->getSpecimen($barcode);
return isset($result);
}
function fetchHtmlUri($barcode) {
$result = $this->getSpecimen($barcode);
......@@ -60,6 +52,15 @@ class BarcodeUtil {
return null;
}
function getIIIF($barcode){
return ($this->isValid($barcode)) ? $this->db->query(Config::get('database')['query_iiif'], [$barcode]) : null;
}
function isInDB($barcode) {
$result = $this->getSpecimen($barcode);
return isset($result);
}
## escapes/converts(to UTF-8) special charaters in assoc. array values
function escape($array) {
$escaped = array();
......
{
"@context": [
"http://www.w3.org/ns/anno.jsonld",
"http://iiif.io/api/presentation/2/context.json"
],
"@type": "sc:Manifest",
"@id": "https://herbarium-dev.bgbm.org/iiif/manifest/manifest.json",
"label": "{{ specimen[config['label']] }}",
"description": "{{ specimen[config['description']] }}",
"metadata": [
{% set first = true %}
{% for element, column in metadata|merge(literals)|merge(resources)|merge(wikidata) %}
{% if specimen[column] is not empty %}
{% if not first %},{% endif %}
{% set first = false %}
{"label":"{{ element }}", "value": "{{ specimen[column] }}"}
{% endif %}
{% endfor %}
],
"attribution": "Botanisches Museum und Botanischer Garten Berlin",
"logo": "https://www.bgbm.org/sites/all/themes/bgbm_fucd20/images/logo_bgbm.jpg",
"sequences": [
{
"@type": "sc:Sequence",
"canvases": [
{% for item in iiif %}
{
"@type": "sc:Canvas",
"@id": "https://herbarium-dev.bgbm.org/iiif/canvas/{{ loop.index }}",
"label": "{{ item[config['filename']] }}",
"width": 6099,
"height": 8599,
"images": [
{
"@type": "oa:Annotation",
"motivation": "sc:painting",
"on": "https://herbarium-dev.bgbm.org/iiif/canvas/{{ loop.index }}",
"resource": {
"@type": "dctypes:Image",
"@id": "{{ config['image_base_url'] ~ item[config['requestpath']]|replace({'!':'/'}) ~ "/" ~ item[config['filename']] }}",
"service": {
"@context": "http://iiif.io/api/image/2/context.json",
"@id": "{{ config['endpoint'] ~ item[config['requestpath']] ~ "!" ~ item[config['filename']] }}",
"profile": "http://iiif.io/api/image/2/level2.json"
}
}
}
]
}
{% if not loop.last %},{% endif %}
{% endfor %}
]
}
]
}
\ No newline at end of file
......@@ -11,6 +11,8 @@
xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
xmlns:owl="http://www.w3.org/2002/07/owl/">
{% set rdfURL = base_url()|replace({'https://':'http://'}) ~ path_for('rdf', {barcode:barcode}) %}
{% set objectURL = base_url()|replace({'https://':'http://'}) ~ path_for('object', {barcode:barcode}) %}
<!--This is metadata about this metadata document-->
<rdf:Description
......@@ -20,7 +22,7 @@
</rdf:Description>
<!--This is metadata about this specimen-->
<rdf:Description rdf:about="{{ objectURL }}">
<rdf:Description rdf:about="{{ objectURL }}">
{% for element, column in literals if specimen[column] is not empty %}
<{{ element }}>{{ specimen[column] }}</{{element}}>
{% endfor %}
......
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "b5e4fb83f49c128ef0c569550e2838e8",
......@@ -297,16 +297,16 @@
},
{
"name": "slim/slim",
"version": "3.12.0",
"version": "3.12.1",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim.git",
"reference": "f4947cc900b6e51cbfda58b9f1247bca2f76f9f0"
"reference": "eaee12ef8d0750db62b8c548016d82fb33addb6b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/f4947cc900b6e51cbfda58b9f1247bca2f76f9f0",
"reference": "f4947cc900b6e51cbfda58b9f1247bca2f76f9f0",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/eaee12ef8d0750db62b8c548016d82fb33addb6b",
"reference": "eaee12ef8d0750db62b8c548016d82fb33addb6b",
"shasum": ""
},
"require": {
......@@ -364,7 +364,7 @@
"micro",
"router"
],
"time": "2019-01-15T13:21:25+00:00"
"time": "2019-04-16T16:47:29+00:00"
},
{
"name": "slim/twig-view",
......@@ -477,16 +477,16 @@
},
{
"name": "twig/twig",
"version": "v1.38.4",
"version": "v1.41.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "7732e9e7017d751313811bd118de61302e9c8b35"
"reference": "575cd5028362da591facde1ef5d7b94553c375c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/7732e9e7017d751313811bd118de61302e9c8b35",
"reference": "7732e9e7017d751313811bd118de61302e9c8b35",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/575cd5028362da591facde1ef5d7b94553c375c9",
"reference": "575cd5028362da591facde1ef5d7b94553c375c9",
"shasum": ""
},
"require": {
......@@ -501,7 +501,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.38-dev"
"dev-master": "1.41-dev"
}
},
"autoload": {
......@@ -539,7 +539,7 @@
"keywords": [
"templating"
],
"time": "2019-03-23T14:27:19+00:00"
"time": "2019-05-14T11:59:08+00:00"
}
],
"packages-dev": [],
......
......@@ -21,11 +21,12 @@ db = ''
; ? Will be replaced with Barcode
; Query to fetch specimen data from database to display in RDF (see below)
query_one = 'SELECT TOP 1 * from trRdf_complete WHERE HerbariumID=?;'
query_all = 'SELECT * from trRdf_complete;'
query_rdf_one = 'SELECT TOP 1 * from trRdf_complete WHERE HerbariumID=?;'
query_rdf_all = 'SELECT * from trRdf_complete;'
query_iiif = 'SELECT * from view_iiif_rdf WHERE HerbariumID=?;'
[rdfmapping/literals]
; Mapping of RDF-Literals to Database Column Names returned by query_one (see above)
; Mapping of RDF-Literals to Database Column Names returned by query_rdf_one (see above)
; Display Example: <dc:title>My Title</dc:title>
dc:title = 'Title'
; You can add and remove RDF-Elements below this to adjust the RDF to your needs
......@@ -56,7 +57,7 @@ dwc:fieldNumber = 'CollectorNumber'
[rdfmapping/resources]
; Mapping of RDF-Resources to Database Column Names returned by query_one (see above)
; Mapping of RDF-Resources to Database Column Names returned by query_rdf_one (see above)
; You can add and remove RDF-Elements from this list to adjust the RDF to your needs
; Display Example: <dwc:associatedMedia rdf:resource="http://subdomain.domain.de/myimage"/>
dwc:associatedMedia = 'Image'
......@@ -67,9 +68,9 @@ rdf:about = 'WIKIDATA_ID'
owl:sameAsHuH = 'HUH_PURL'
owl:sameAsViaf = 'VIAF_ID'
[rdfmapping/iif]
[rdfmapping/iiif]
; Mapping of Relation-Fields linking to IIF-Data to Database Column Names
; returned by query_one (see above)
; returned by query_rdf_one (see above)
; Display Example:
; <dc:relation>
; <rdf:Description rdf:about="http://iiif.rbge.info/iiif/E00421509" >
......@@ -81,10 +82,10 @@ owl:sameAsViaf = 'VIAF_ID'
; <dc:created>2011-08-22T11:54:43Z</dc:created>
; </rdf:Description>
; </dc:relation>
rdf:Description = 'iifID'
dc:identifier = 'iifID'
rdf:Description = 'iiifID'
dc:identifier = 'iiifID'
dc:subject = 'ObjectURI'
dc:created = 'iifCreated'
dc:created = 'iiifCreated'
; Interpreted as string, not as column name
dc:type = 'http://iiif.io/api/presentation/3#Manifest'
......@@ -98,8 +99,25 @@ dc:description = 'A IIIF resource for this specimen.'
catalog_uri = 'http://herbarium.bgbm.org/data/rdf/catalog'
object_base_uri = 'http://herbarium.bgbm.org/object'
; Database Column Name for Specimen Object URI returned by query_one (see above)
; Database Column Name for Specimen Object URI returned by query_rdf_one (see above)
rdf:about = 'ObjectURI'
; Database Column Name for Specimen Title returned by query_one (see above)
; Database Column Name for Specimen Title returned by query_rdf_one (see above)
dc:title = 'Title'
[iiif]
; IIIF API Endpoint (e.g. provided by digilib)
endpoint = 'https://pictures.bgbm.org/digilib/Scaler/IIIF/'
image_base_url = 'https://pictures.bgbm.org/digilib/digilib.html?fn='
; Mapping of IIIF manifest parameters to Database Column Names returned by query_rdf_one (see above)
description = 'TitleDescription'
label = 'Title'
; Column Names returned by query_iiif (see above) containing the digilib request path and file name
requestpath = 'RequestPath'
filename = 'name'
[iiif/metadata]
CETAF_ID = ObjectURI
......@@ -2,12 +2,13 @@
require_once('../app/Bootstrap.php');
use \StableIdentifier\Config;
use \StableIdentifier\BarcodeUtil;
use \StableIdentifier\DatabaseUtil;
use ptlis\ConNeg\Negotiation;
$app->get('/object[/[{barcode}]]', function ($request, $response, $args) {
## Barcode Utility Class
$barcodeUtil = new BarcodeUtil();
$app->group('/object', function() use ($app) {
$app->get('[/[{barcode}]]', function ($request, $response, $args) {
## Barcode DatabaseUtility Class
$databaseUtil = new DatabaseUtil();
## Check if barcode is given in path or as query parameter
$params = $request->getParams();
......@@ -21,7 +22,7 @@ $app->get('/object[/[{barcode}]]', function ($request, $response, $args) {
if(!isset($barcode)){
## rdf
if($bestContentType === Config::get('contenttypes')['rdf']){
$specimens = $barcodeUtil->getAllSpecimenEscaped();
$specimens = $databaseUtil->getAllSpecimenEscaped();
return $this->view->render($response, 'sitemap.rdf.template.twig', [
'specimens' => $specimens,
'config' => Config::get('sitemap')
......@@ -31,7 +32,7 @@ $app->get('/object[/[{barcode}]]', function ($request, $response, $args) {
}
## If barcode was not found in DB, return 404
if(!$barcodeUtil->isInDB($barcode))
if(!$databaseUtil->isInDB($barcode))
return $this->view->render($response, '404.template.twig')->withStatus(404);
## html
......@@ -46,12 +47,43 @@ $app->get('/object[/[{barcode}]]', function ($request, $response, $args) {
## nothing
return $this->view->render($response, '406.template.twig')->withStatus(406);
})->setName('object');
})->setName('object');
$app->get('/{barcode}/manifest.json', function ($request, $response, $args) {
$barcode = $args['barcode'];
## Barcode DatabaseUtility Class
$databaseUtil = new DatabaseUtil();
## Get specimen from db by barcode
$specimen = $databaseUtil->getSpecimenEscaped($barcode);
$iiif = $databaseUtil->getIIIF($barcode);
//return $response->withJSON($iiif);
## If no iiif data for barcode was found, return 404
if(!isset($iiif))
return $this->view->render($response, '404.template.twig')->withStatus(404);
return $this->view->render($response, 'specimen.manifest.template.twig', [
'barcode' => $barcode,
'specimen' => $specimen,
'literals' => Config::get('rdfmapping/literals'),
'resources'=> Config::get('rdfmapping/resources'),
'wikidata'=> Config::get('rdfmapping/wikidata'),
'iiif' => $iiif,
'config' => Config::get('iiif'),
'metadata' => Config::get('iiif/metadata')
])->withHeader('Content-type', 'application/json')
->withHeader("Access-Control-Allow-Origin","*")
->withHeader("Access-Control-Allow-Methods","GET");
})->setName('manifest');
});
$app->group('/data', function() use ($app) {
$app->get('/page[/[{barcode}]]', function ($request, $response, $args) {
## Barcode Utility Class
$barcodeUtil = new BarcodeUtil();
## Barcode DatabaseUtility Class
$databaseUtil = new DatabaseUtil();
## Check if barcode is given in path or as query parameter
$params = $request->getParams();
......@@ -62,19 +94,19 @@ $app->group('/data', function() use ($app) {
return $response->withRedirect(Config::get('urls')['catalog_url'], 303);
## If barcode was not found in DB, return 404
if(!$barcodeUtil->isInDB($barcode))
if(!$databaseUtil->isInDB($barcode))
return $this->view->render($response, '404.template.twig')->withStatus(404);
## Get URL for redirect
$htmlUri = $barcodeUtil->fetchHtmlUri($barcode);
$htmlUri = $databaseUtil->fetchHtmlUri($barcode);
if(!isset($htmlUri) || empty($htmlUri))
return $response->withRedirect(sprintf(Config::get('urls')['html_url'], $barcode), 303);
return $response->withRedirect($htmlUri, 303);
})->setName('page');
$app->get('/rdf[/[{barcode}]]', function ($request, $response, $args) {
## Barcode Utility Class
$barcodeUtil = new BarcodeUtil();
## Barcode DatabaseUtility Class
$databaseUtil = new DatabaseUtil();
## Check if barcode is given in path or as query parameter
$params = $request->getParams();
......@@ -82,7 +114,7 @@ $app->group('/data', function() use ($app) {
## If no barcode is given, return sitemap
if(!isset($barcode)){
$specimens = $barcodeUtil->getAllSpecimenEscaped();
$specimens = $databaseUtil->getAllSpecimenEscaped();
return $this->view->render($response, 'sitemap.rdf.template.twig', [
'specimens' => $specimens,
'config' => Config::get('sitemap')
......@@ -90,7 +122,7 @@ $app->group('/data', function() use ($app) {
}
## Get specimen from db by barcode
$specimen = $barcodeUtil->getSpecimenEscaped($barcode);
$specimen = $databaseUtil->getSpecimenEscaped($barcode);
## If no specimen for barcode was found, return 404
if(!isset($specimen))
......@@ -98,10 +130,7 @@ $app->group('/data', function() use ($app) {
## Return specimen RDF
return $this->view->render($response, 'specimen.rdf.template.twig', [
'objectURL' => str_replace('https://','http://',$request->getUri()->getBaseUrl()).$this->get('router')->pathFor('object', [
'barcode' => $barcode]),
'rdfURL' => str_replace('https://','http://',$request->getUri()->getBaseUrl()).$this->get('router')->pathFor('rdf', [
'barcode' => $barcode]),
'barcode' => $barcode,
'specimen' => $specimen,
'literals' => Config::get('rdfmapping/literals'),
'resources'=> Config::get('rdfmapping/resources'),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment