View source
<?php
class ServicesClientConnectionRestServer extends ServicesClientConnectionServer {
protected $parser;
protected $formatter;
protected $rest_actions = array(
'retrieve' => 'GET',
'update' => 'PUT',
'create' => 'POST',
'delete' => 'DELETE',
);
public function __construct($connection, $config, $client = NULL) {
parent::__construct($connection, $config, $client);
$parser = isset($this->config['response_parser']) ? $this->config['response_parser'] : NULL;
$this->parser = new ServicesClientConnectionRestServerParser($parser);
$formatter = isset($this->config['request_formatter']) ? $this->config['request_formatter'] : NULL;
$this->formatter = new ServicesClientConnectionRestServerFormatter($formatter);
}
public function configForm(&$form, &$form_state) {
$form['request_formatter'] = array(
'#type' => 'select',
'#title' => t('Request formatter'),
'#options' => ServicesClientConnectionRestServerFormatter::getFormatters(),
'#default_value' => isset($this->config['request_formatter']) ? $this->config['request_formatter'] : '',
);
$form['response_parser'] = array(
'#type' => 'select',
'#title' => t('Response parser'),
'#options' => ServicesClientConnectionRestServerParser::getParsers(),
'#default_value' => isset($this->config['response_parser']) ? $this->config['response_parser'] : '',
);
}
public function configFormSubmit(&$form, &$form_state) {
$form_state['config'] = array(
'request_formatter' => $form_state['values']['request_formatter'],
'response_parser' => $form_state['values']['response_parser'],
);
}
public function prepareRequest(ServicesClientConnectionHttpRequest &$request) {
parent::prepareRequest($request);
$endpoint = rtrim($this->connection->endpoint, '/');
$url_parts = array(
$endpoint,
$request->resource,
);
if ($request->id) {
$url_parts[] = urlencode($request->id);
}
if (in_array($request->action, array_keys($this->rest_actions))) {
$request->http_method = $this->rest_actions[$request->action];
}
elseif (!empty($request->relation)) {
$url_parts[] = $request->relation;
$request->http_method = 'GET';
}
elseif (!empty($request->action)) {
$url_parts[] = $request->action;
$request->http_method = 'POST';
}
elseif (empty($request->http_method)) {
$request->http_method = 'POST';
}
if (empty($request->url)) {
$request->url = implode('/', $url_parts);
}
else {
$request->url = $endpoint . '/' . ltrim($request->url, '/');
}
$this->parser
->prepareRequest($request);
$this->formatter
->format($request);
}
public function processResponse(ServicesClientConnectionResponse &$response) {
parent::processResponse($response);
if (ServicesClientConnectionHttp::isError($response->response_code)) {
$response->error_code = $response->response_code;
$response->error_message = ServicesClientConnectionHttp::getHttpMessage($response->response_code);
}
else {
$response->data = $this->parser
->parse($response->raw_response);
}
}
}
class ServicesClientConnectionRestServerFormatter {
protected static $request_formatters = array(
'php' => array(
'title' => 'PHP Serialized',
'method' => 'formatSerialize',
'content_type' => 'application/vnd.php.serialized',
),
'json' => array(
'title' => 'JSON',
'method' => 'formatJson',
'content_type' => 'application/json',
),
'urlencode' => array(
'title' => 'URL Encode',
'method' => 'formatUrlEncode',
'content_type' => 'application/x-www-form-urlencoded',
),
'formdata' => array(
'title' => 'Multipart Data',
'method' => 'formatMultipart',
'content_type' => 'multipart/form-data',
),
);
public static function getFormatters() {
$output = array();
foreach (self::$request_formatters as $id => $info) {
$output[$id] = $info['title'];
}
return $output;
}
protected $formatter;
public function __construct($formatter) {
$this->formatter = $formatter;
}
protected function getFormatterInfo($property = NULL) {
$formatter = isset(self::$request_formatters[$this->formatter]) ? self::$request_formatters[$this->formatter] : NULL;
if (!empty($property) && !empty($formatter)) {
return isset($formatter[$property]) ? $formatter[$property] : NULL;
}
return $formatter;
}
public function format(&$request) {
$request->data_raw = $request->data;
if ($request->http_method != 'GET') {
if (!empty($request->data) && ($method = $this
->getFormatterInfo('method'))) {
$request->data = call_user_func_array(array(
$this,
$method,
), array(
$request->data,
$request,
));
}
elseif (empty($request->data)) {
$request->data = '';
}
}
if ($content_type = $this
->getFormatterInfo('content_type')) {
$request->http_headers['Content-Type'] = $content_type;
}
}
protected function formatSerialize($data) {
return serialize($data);
}
protected function formatJson($data) {
return json_encode($data);
}
protected function formatUrlEncode($data) {
return http_build_query($data, NULL, '&');
}
protected function formatMultipart($data) {
return $data;
}
}
class ServicesClientConnectionRestServerParser {
private static $parsers = array(
'json' => array(
'title' => 'JSON',
'accept' => 'application/json',
'method' => 'parseJson',
),
'php' => array(
'title' => 'PHP serialized',
'accept' => 'application/vnd.php.serialized',
'method' => 'parseSerialized',
),
'xml' => array(
'title' => 'XML',
'accept' => 'application/xml',
'method' => 'parseXml',
),
);
public static function getParsers() {
$output = array();
foreach (self::$parsers as $id => $info) {
$output[$id] = $info['title'];
}
return $output;
}
private $parser;
public function __construct($parser) {
$this->parser = $parser;
}
public function parse($data) {
if ($method = $this
->getParserInfo('method')) {
return call_user_func(array(
$this,
$method,
), $data);
}
}
public function prepareRequest(&$request) {
if ($accept = $this
->getParserInfo('accept')) {
$request->http_headers['Accept'] = $accept;
}
}
protected function parseJson($data) {
$parsed = json_decode($data, TRUE);
if (is_object($parsed)) {
$parsed = (array) $parsed;
}
return $parsed;
}
protected function parseSerialized($data) {
return (array) unserialize($data);
}
protected function parseXml($data) {
return (array) simplexml_load_string($data);
}
protected function getParserInfo($property = NULL) {
$parser = isset(self::$parsers[$this->parser]) ? self::$parsers[$this->parser] : NULL;
if (!empty($property) && !empty($parser)) {
return isset($parser[$property]) ? $parser[$property] : NULL;
}
return $parser;
}
}