class FormatterJson in RESTful 7.2
Class FormatterHalJson.
@package Drupal\restful\Plugin\formatter
Plugin annotation
@Formatter(
id = "json",
label = "Simple JSON",
description = "Output in using the JSON format."
)
Hierarchy
- class \Drupal\restful\Plugin\formatter\Formatter extends \Drupal\Component\Plugin\PluginBase implements FormatterInterface uses ConfigurablePluginTrait
- class \Drupal\restful\Plugin\formatter\FormatterJson implements FormatterInterface
Expanded class hierarchy of FormatterJson
File
- src/
Plugin/ formatter/ FormatterJson.php, line 27 - Contains \Drupal\restful\Plugin\formatter\FormatterJson.
Namespace
Drupal\restful\Plugin\formatterView source
class FormatterJson extends Formatter implements FormatterInterface {
/**
* Content Type.
*
* @var string
*/
protected $contentType = 'application/json; charset=utf-8';
/**
* {@inheritdoc}
*/
public function prepare(array $data) {
// If we're returning an error then set the content type to
// 'application/problem+json; charset=utf-8'.
if (!empty($data['status']) && floor($data['status'] / 100) != 2) {
$this->contentType = 'application/problem+json; charset=utf-8';
return $data;
}
$extracted = $this
->extractFieldValues($data);
$output = array(
'data' => $this
->limitFields($extracted),
);
if ($resource = $this
->getResource()) {
$request = $resource
->getRequest();
$data_provider = $resource
->getDataProvider();
if ($request
->isListRequest($resource
->getPath())) {
// Get the total number of items for the current request without
// pagination.
$output['count'] = $data_provider
->count();
// If there are items that were taken out during access checks,
// report them as denied in the metadata.
if (variable_get('restful_show_access_denied', FALSE) && ($inaccessible_records = $data_provider
->getMetadata()
->get('inaccessible_records'))) {
$output['denied'] = empty($output['meta']['denied']) ? $inaccessible_records : $output['meta']['denied'] + $inaccessible_records;
}
}
if (method_exists($resource, 'additionalHateoas')) {
$output = array_merge($output, $resource
->additionalHateoas($output));
}
// Add HATEOAS to the output.
$this
->addHateoas($output);
}
return $output;
}
/**
* Extracts the actual values from the resource fields.
*
* @param array[]|ResourceFieldCollectionInterface $data
* The array of rows or a ResourceFieldCollection.
* @param string[] $parents
* An array that holds the name of the parent fields that lead to the
* current data structure.
* @param string[] $parent_hashes
* An array that holds the name of the parent cache hashes that lead to the
* current data structure.
*
* @return array[]
* The array of prepared data.
*
* @throws InternalServerErrorException
*/
protected function extractFieldValues($data, array $parents = array(), array &$parent_hashes = array()) {
$output = array();
if ($this
->isCacheEnabled($data)) {
$parent_hashes[] = $this
->getCacheHash($data);
if ($cache = $this
->getCachedData($data)) {
return $cache->data;
}
}
foreach ($data as $public_field_name => $resource_field) {
if (!$resource_field instanceof ResourceFieldInterface) {
// If $resource_field is not a ResourceFieldInterface it means that we
// are dealing with a nested structure of some sort. If it is an array
// we process it as a set of rows, if not then use the value directly.
$parents[] = $public_field_name;
$output[$public_field_name] = static::isIterable($resource_field) ? $this
->extractFieldValues($resource_field, $parents, $parent_hashes) : $resource_field;
continue;
}
if (!$data instanceof ResourceFieldCollectionInterface) {
throw new InternalServerErrorException('Inconsistent output.');
}
// This feels a bit awkward, but if the result is going to be cached, it
// pays off the extra effort of generating the whole resource entity. That
// way we can get a different field set with the previously cached entity.
// If the entity is not going to be cached, then avoid generating the
// field data altogether.
$limit_fields = $data
->getLimitFields();
if (!$this
->isCacheEnabled($data) && $limit_fields && !in_array($resource_field
->getPublicName(), $limit_fields)) {
// We are not going to cache this and this field is not in the output.
continue;
}
$value = $resource_field
->render($data
->getInterpreter());
// If the field points to a resource that can be included, include it
// right away.
if (static::isIterable($value) && $resource_field instanceof ResourceFieldResourceInterface) {
$value = $this
->extractFieldValues($value, $parents, $parent_hashes);
}
$output[$public_field_name] = $value;
}
if ($this
->isCacheEnabled($data)) {
$this
->setCachedData($data, $output, $parent_hashes);
}
return $output;
}
/**
* Add HATEOAS links to list of item.
*
* @param array $data
* The data array after initial massaging.
*/
protected function addHateoas(array &$data) {
if (!($resource = $this
->getResource())) {
return;
}
$request = $resource
->getRequest();
// Get self link.
$data['self'] = array(
'title' => 'Self',
'href' => $resource
->versionedUrl($resource
->getPath()),
);
$input = $request
->getParsedInput();
unset($input['page']);
unset($input['range']);
$input['page'] = $request
->getPagerInput();
$page = $input['page']['number'];
if ($page > 1) {
$query = $input;
$query['page']['number'] = $page - 1;
$data['previous'] = array(
'title' => 'Previous',
'href' => $resource
->versionedUrl('', array(
'query' => $query,
), TRUE),
);
}
// We know that there are more pages if the total count is bigger than the
// number of items of the current request plus the number of items in
// previous pages.
$items_per_page = $this
->calculateItemsPerPage($resource);
$previous_items = ($page - 1) * $items_per_page;
if (isset($data['count']) && $data['count'] > count($data['data']) + $previous_items) {
$query = $input;
$query['page']['number'] = $page + 1;
$data['next'] = array(
'title' => 'Next',
'href' => $resource
->versionedUrl('', array(
'query' => $query,
), TRUE),
);
}
}
/**
* {@inheritdoc}
*/
public function render(array $structured_data) {
return drupal_json_encode($structured_data);
}
/**
* {@inheritdoc}
*/
public function getContentTypeHeader() {
return $this->contentType;
}
/**
* {@inheritdoc}
*/
public function parseBody($body) {
if (!($decoded_json = drupal_json_decode($body))) {
throw new BadRequestException(sprintf('Invalid JSON provided: %s.', $body));
}
return $decoded_json;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ConfigurablePluginTrait:: |
protected | property | Plugin instance configuration. | |
ConfigurablePluginTrait:: |
public | function | ||
ConfigurablePluginTrait:: |
public | function | 1 | |
ConfigurablePluginTrait:: |
public | function | ||
ConfigurablePluginTrait:: |
public | function | ||
Formatter:: |
protected | property | The resource handler containing more info about the request. | |
Formatter:: |
protected static | function | Gets a cache fragments based on the data to be rendered. | |
Formatter:: |
protected | function | Helper function that calculates the number of items per page. | |
Formatter:: |
protected | function | Gets a cache controller based on the data to be rendered. | |
Formatter:: |
public | function |
Formats the un-structured data into the output format. Overrides FormatterInterface:: |
|
Formatter:: |
protected | function | Gets the cached computed value for the fields to be rendered. | |
Formatter:: |
protected | function | Gets the cached computed value for the fields to be rendered. | |
Formatter:: |
public | function |
Gets the underlying resource. Overrides FormatterInterface:: |
|
Formatter:: |
protected | function | Checks if the passed in data to be rendered can be cached. | |
Formatter:: |
protected static | function | Helper function to know if a variable is iterable or not. | |
Formatter:: |
protected | function | Returns only the allowed fields by filtering out the other ones. | |
Formatter:: |
protected | function | Gets the cached computed value for the fields to be rendered. | |
Formatter:: |
public | function |
Sets the underlying resource. Overrides FormatterInterface:: |
|
Formatter:: |
protected static | function | Given a prefix, return the allowed fields that apply removing the prefix. | |
Formatter:: |
public | function | ||
FormatterJson:: |
protected | property | Content Type. | 1 |
FormatterJson:: |
protected | function | Add HATEOAS links to list of item. | |
FormatterJson:: |
protected | function | Extracts the actual values from the resource fields. | |
FormatterJson:: |
public | function |
Returns the content type for the selected output format. Overrides Formatter:: |
|
FormatterJson:: |
public | function |
Parses the body string into the common format. Overrides Formatter:: |
|
FormatterJson:: |
public | function |
Massages the raw data to create a structured array to pass to the renderer. Overrides FormatterInterface:: |
1 |
FormatterJson:: |
public | function |
Renders an array in the selected format. Overrides FormatterInterface:: |