-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.php
175 lines (158 loc) · 5.58 KB
/
index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
<?php
/**
* easyLOD, an application that exposes content as Linked Open Data. Uses plugins
* to get data from different sources. Written in the Slim micro-framework,
* slimframework.com.
*
* Distributed under the MIT License, http://opensource.org/licenses/MIT.
*/
// Slim setup.
require 'lib/Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim();
// Get the plugin config file and provide a default value for
// $plugins if the file cannot be loaded.
include('plugins.php');
if (!isset($plugins)) {
$plugins = array();
}
/**
* Route for /resource. Redirect browsers that supply a request header of
* Accept: application/rdf+xml to this URI get back an RDF representation
* of the metadata for the item identified in the request. Redirects other
* browsers (e.g., browsers used by humans) to whatever is defined by the
* source plugin's getWebPage() function.
*
* @param string $identifier
* Tokenized by Slim from :identifier.
*
* @param object $app
* The global $app object instantiated at the top of this file.
*/
$app->get('/resource/:identifier', function ($identifier) use ($app) {
$plugin = getDataSourcePlugin($identifier, $app);
$request = $app->request();
// If the request is from a Linked Data browser (that is, one issuing a
// Accept: application/rdf+xml request header), redirect it to the 'data' URL.
// Temporary regex match until Slim supports content negotiation: see
// http://help.slimframework.com/discussions/questions/65-content-types.
if (preg_match('/application\/rdf\+xml/', $request->headers('Accept'))) {
$data_path = swapPaths($request->getPath(), 'data');
$url = $request->getUrl() . $data_path;
$app->response()->header('Content-Type', 'application/rdf+xml');
$app->response()->header('Vary', 'Accept');
$app->redirect($url, 303);
}
// If the request is not from a Linked Data browser, redirect it to a human-readable
// page for the item.
else {
require 'data_sources/' . $plugin . '/' . $plugin . '.php';
getWebPage($identifier, $app);
}
});
/**
* Route for /data. Returns the RDF representation of the item, after
* adding metadata generated by the appropriate data source plugin.
*
* @param string $identifier
* Tokenized by Slim from :identifier.
*
* @param object $app
* The global $app object instantiated at the top of this file.
*/
$app->get('/data/:identifier', function ($identifier) use ($app) {
// Get the identifier namespace so we can use the corresponding data
// source plugin.
$plugin = getDataSourcePlugin($identifier, $app);
require 'data_sources/' . $plugin . '/' . $plugin . '.php';
$request = $app->request();
$app->response()->header('Content-Type', 'application/rdf+xml');
$xml = new XMLWriter();
$xml->openMemory();
// Check to see if the data source plugin is supplying raw XML and if
// so, return the XML to the client.
if (function_exists('getResourceDataRaw')) {
$xml = getResourceDataRaw($identifier, $xml, $app);
echo $xml->outputMemory();
// We need to return TRUE to get Slim to ouput the correct Content-Type header.
return TRUE;
}
// If the data source plugin is not returning raw XML, start generating the
// output XML.
$xml->setIndent(TRUE);
$xml->startDocument('1.0', 'utf-8', NULL);
$xml->startElementNS('rdf', 'RDF', NULL);
// Add XML namespaces, including any supplied by the data source plugin,
// to the <RDF> element.
$rdf_namespace = array('xmlns:rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
$data_source_namespaces = getDataSourceNamespaces();
$namespaces = array_merge($rdf_namespace, $data_source_namespaces);
foreach ($namespaces as $prefix => $uri) {
$xml->writeAttribute($prefix, $uri);
}
$xml->startElementNS('rdf', 'Description', NULL);
$resource_path = swapPaths($request->getPath(), 'resource');
$xml->writeAttributeNS('rdf', 'about', NULL, $request->getUrl() . $resource_path);
// Add the XML generated from the source plugin.
$xml = getResourceData($identifier, $xml, $app);
$xml->endElement(); // <Description>
$xml->endElement(); // <RDF>
echo $xml->outputMemory();
});
$app->run();
/**
* Functions.
*/
/**
* Determine which plugin to invoke. If a plugin file can't be
* found, return a 404.
*
* @param string $identifier
* The entire identifier string, containing a namespace, then a colon,
* then an ID.
*
* @param object $app
* The global $app object instantiated at the top of this file.
*/
function getDataSourcePlugin($identifier, $app) {
global $plugins;
list($namespace, $id) = explode(':', $identifier);
if (array_key_exists($namespace, $plugins)) {
$plugin = $plugins[$namespace]['plugin'];
if (file_exists('data_sources/' . $plugin . '/' . $plugin . '.php')) {
return $plugins[$namespace]['plugin'];
}
else {
$app->halt(404, 'Resource not found');
}
}
else {
$plugin = $namespace;
if (file_exists('data_sources/' . $plugin . '/' . $plugin . '.php')) {
return $namespace;
}
else {
$app->halt(404, 'Resource not found');
}
}
}
/**
* If the path in $original is the 'resource' path, convert it
* to the 'data' path, and vice versa. We do this to ensure that
* incoming requests get redirected to either the /resource or
* /data routes.
*
* @param string $original
* The URI path of the original request.
*
* @param string $new
* Either 'data' or 'resource'
*/
function swapPaths($original, $new) {
if ($new == 'data') {
return preg_replace('/\/resource\//', '/data/', $original);
}
if ($new = 'resource') {
return preg_replace('/\/data\//', '/resource/', $original);
}
}