/** * 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})."); } } } }