/**
* Retrieve a Data object identified by $uri
*
* @param string $uri The identifier that identifies a resource
*
* @return \Response
*/
public function get($uri)
{
// Check permissions
Auth::requirePermissions('dataset.view');
// Split for an (optional) extension
list($uri, $extension) = $this->processURI($uri);
// Check for caching
// Based on: URI / Rest parameters / Query parameters / Paging headers
$cache_string = $uri;
list($limit, $offset) = Pager::calculateLimitAndOffset();
$cache_string .= '/limit=' . $limit . 'offset=' . $offset;
$omit = ['limit', 'offset', 'page', 'page_size'];
$query_string_params = \Input::get();
foreach ($query_string_params as $key => $val) {
if (in_array($key, $omit)) {
unset($query_string_params[$key]);
}
}
$cache_string .= http_build_query($query_string_params);
$cache_string = sha1($cache_string);
if (Cache::has($cache_string)) {
return ContentNegotiator::getResponse(Cache::get($cache_string), $extension);
} else {
// Get definition
$definition = $this->definition->getByIdentifier($uri);
if ($definition) {
// Get source definition
$source_definition = $this->definition->getDefinitionSource($definition['source_id'], $definition['source_type']);
if ($source_definition) {
$source_type = $source_definition['type'];
// Create the right datacontroller
$controller_class = 'Tdt\\Core\\DataControllers\\' . $source_type . 'Controller';
$data_controller = \App::make($controller_class);
// Get REST parameters
$uri_segments = explode('/', $uri);
$rest_parameters = array_diff($uri_segments, array($definition['collection_uri'], $definition['resource_name']));
$rest_parameters = array_values($rest_parameters);
$throttle_response = $this->applyThrottle($definition);
if (!empty($throttle_response)) {
return $throttle_response;
}
// Retrieve dataobject from datacontroller
$data = $data_controller->readData($source_definition, $rest_parameters);
// If the source type is XML, just return the XML contents, don't transform
if (strtolower($source_type) == 'xml' && $extension == 'xml') {
return $this->createXMLResponse($data->data);
}
$data->rest_parameters = $rest_parameters;
// REST filtering
if ($source_type != 'INSTALLED' && count($data->rest_parameters) > 0) {
$data->data = self::applyRestFilter($data->data, $data->rest_parameters);
}
// Semantic paging with the hydra voc
if ($data->is_semantic && !empty($data->paging)) {
\EasyRdf_Namespace::set('hydra', 'http://www.w3.org/ns/hydra/core#');
$graph = $data->data;
$url = \URL::to($definition['collection_uri'] . '/' . $definition['resource_name']);
$request_url = \Request::url();
$graph->addResource($request_url, 'void:subset', $url);
foreach ($data->paging as $key => $val) {
$paged_url = $request_url . '?offset=' . $val[0] . '&limit=' . $val[1] . Pager::buildQuerystring();
switch ($key) {
case 'next':
$graph->addResource($request_url, 'hydra:nextPage', $paged_url);
break;
case 'previous':
$graph->addResource($request_url, 'hydra:previousPage', $paged_url);
break;
case 'last':
$graph->addResource($request_url, 'hydra:lastPage', $paged_url);
break;
case 'first':
$graph->addResource($request_url, 'hydra:firstPage', $paged_url);
break;
}
}
$graph->addResource($url, 'a', 'dcat:Dataset');
$title = null;
if (!empty($definition['title'])) {
$title = $definition['title'];
} else {
$title = $definition['collection_uri'] . '/' . $definition['resource_name'];
}
$graph->addLiteral($url, 'dc:title', $title);
$graph->addLiteral($url, 'dc:description', $source_definition['description']);
$graph->addResource($url, 'dcat:distribution', $url . '.json');
$data->data = $graph;
}
// Add definition to the object
$data->definition = $definition;
// Add source definition to the object
$data->source_definition = $source_definition;
// Add the available, supported formats to the object
$format_helper = new FormatHelper();
$data->formats = $format_helper->getAvailableFormats($data);
// Store in cache
Cache::put($cache_string, $data, $source_definition['cache']);
// Return the formatted response with content negotiation
return ContentNegotiator::getResponse($data, $extension);
} else {
\App::abort(404, "Source for the definition could not be found.");
}
} else {
// Coulnd't find a definition, but it might be a collection
$resources = $this->definition->getByCollection($uri);
if (count($resources) > 0) {
$data = new Data();
$data->data = new \stdClass();
$data->data->datasets = array();
$data->data->collections = array();
foreach ($resources as $res) {
// Check if it's a subcollection or a dataset
$collection_uri = rtrim($res['collection_uri'], '/');
if ($collection_uri == $uri) {
array_push($data->data->datasets, \URL::to($collection_uri . '/' . $res['resource_name']));
} else {
// Push the subcollection if it's not already in the array
if (!in_array(\URL::to($collection_uri), $data->data->collections)) {
array_push($data->data->collections, \URL::to($collection_uri));
}
}
}
// Fake a definition
$data->definition = new \Definition();
$uri_array = explode('/', $uri);
$last_chunk = array_pop($uri_array);
$data->definition->collection_uri = join('/', $uri_array);
$data->definition->resource_name = $last_chunk;
// Return the formatted response with content negotiation
return ContentNegotiator::getResponse($data, $extension);
} else {
\App::abort(404, "The dataset or collection you were looking for could not be found (URI: {$uri}).");
}
}
}
}