View source
<?php
namespace Drupal\restful\Formatter;
use Drupal\restful\Exception\ServiceUnavailableException;
use Drupal\restful\Http\HttpHeader;
use Drupal\restful\Plugin\formatter\FormatterInterface;
use Drupal\restful\Plugin\resource\ResourceInterface;
use Drupal\restful\Plugin\FormatterPluginManager;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\restful\Resource\ResourceManager;
class FormatterManager implements FormatterManagerInterface {
protected $plugins;
protected $resource;
public function __construct($resource = NULL) {
$this->resource = $resource;
$manager = FormatterPluginManager::create();
$options = array();
foreach ($manager
->getDefinitions() as $plugin_id => $plugin_definition) {
$options[$plugin_id] = $plugin_definition;
}
$this->plugins = new FormatterPluginCollection($manager, $options);
}
public function setResource($resource) {
$this->resource = $resource;
}
public function format(array $data, $formatter_name = NULL) {
return $this
->processData('format', $data, $formatter_name);
}
public function render(array $data, $formatter_name = NULL) {
return $this
->processData('render', $data, $formatter_name);
}
public function negotiateFormatter($accept, $formatter_name = NULL) {
$message = 'Formatter plugin class was not found.';
$default_formatter_name = variable_get('restful_default_output_formatter', 'json');
try {
if ($formatter_name) {
return $this
->getPluginByName($formatter_name);
}
if (empty($accept) || $accept == '*/*') {
return $this
->getPluginByName($default_formatter_name);
}
foreach (explode(',', $accept) as $accepted_content_type) {
$accepted_content_type = trim($accepted_content_type);
if (strpos($accepted_content_type, '*/*') === 0) {
return $this
->getPluginByName($default_formatter_name);
}
foreach ($this->plugins as $formatter_name => $formatter) {
if (static::matchContentType($formatter
->getContentTypeHeader(), $accepted_content_type)) {
$formatter
->setConfiguration(array(
'resource' => $this->resource,
));
return $formatter;
}
}
}
} catch (PluginNotFoundException $e) {
$message = $e
->getMessage();
}
throw new ServiceUnavailableException($message);
}
protected function processData($method, array $data, $formatter_name = NULL) {
if ($resource = $this->resource) {
$request = $resource
->getRequest();
}
else {
$request = restful()
->getRequest();
}
$accept = $request
->getHeaders()
->get('accept')
->getValueString();
$formatter = $this
->negotiateFormatter($accept, $formatter_name);
$output = ResourceManager::executeCallback(array(
$formatter,
$method,
), array(
$data,
$formatter_name,
));
$content_type = $formatter
->getContentTypeHeader();
$response_headers = restful()
->getResponse()
->getHeaders();
$response_headers
->add(HttpHeader::create('Content-Type', $content_type));
return $output;
}
protected static function matchContentType($content_type, $pattern) {
$regexps =& drupal_static(__METHOD__);
if (!isset($regexps[$pattern])) {
$to_replace = array(
'/\\\\\\*/',
);
$replacements = array(
'.*',
);
$patterns_quoted = preg_quote($pattern, '/');
$regexps[$pattern] = '/^(' . preg_replace($to_replace, $replacements, $patterns_quoted) . ')(;.*)?$/i';
}
return (bool) preg_match($regexps[$pattern], $content_type);
}
public function getPlugins() {
return $this->plugins;
}
public function getPlugin($instance_id) {
return $this->plugins
->get($instance_id);
}
protected function getPluginByName($name) {
$formatter = $this->plugins
->get($name);
if ($this->resource) {
$formatter
->setResource($this->resource);
}
return $formatter;
}
}