public function RESTServer::handle in Services 6.3
Same name and namespace in other branches
- 7.3 servers/rest_server/includes/RESTServer.inc \RESTServer::handle()
Handles the call to the REST server
Parameters
string $canonical_path:
string $endpoint_path:
Return value
void
File
- servers/
rest_server/ includes/ RESTServer.inc, line 18 - Class for handling REST calls.
Class
- RESTServer
- @file Class for handling REST calls.
Code
public function handle($canonical_path, $endpoint_path) {
$this->endpoint_path = $endpoint_path;
services_set_server_info('resource_uri_formatter', array(
&$this,
'uri_formatter',
));
// Determine the request method
$method = $_SERVER['REQUEST_METHOD'];
if ($method == 'POST' && isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
$method = $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'];
}
if ($method == 'POST' && (isset($_GET['_method']) && $_GET['_method'])) {
$method = $_GET['_method'];
}
if (isset($_GET['_method'])) {
unset($_GET['_method']);
}
// Extract response format info from the canonical path.
$matches = array();
$response_format = '';
if (preg_match('/^(.+)\\.([^\\.^\\/]+)$/', $canonical_path, $matches)) {
$canonical_path = $matches[1];
$response_format = $matches[2];
}
// Prepare $path array and $resource_name.
$path = explode('/', $canonical_path);
$resource_name = array_shift($path);
// Response will vary with accept headers
// if no format was supplied as path suffix
if (empty($response_format)) {
drupal_set_header('Vary: Accept');
}
$endpoint = services_get_server_info('endpoint', '');
$endpoint_definition = services_endpoint_load($endpoint);
$this->endpoint = $endpoint_definition;
// Get the server settings from the endpoint.
$this->settings = !empty($endpoint_definition->server_settings['rest_server']) ? $endpoint_definition->server_settings['rest_server'] : array();
// Normalize the settings so that we get the expected structure
// and sensible defaults.
$this->settings = rest_server_setup_settings($this->settings);
$resources = services_get_resources($endpoint);
$controller = FALSE;
if (!empty($resource_name) && isset($resources[$resource_name])) {
$resource = $resources[$resource_name];
// Get the operation and fill with default values
$controller = $this
->resolveController($resource, $method, $path);
}
else {
//This will stop the 404 from happening when you request just the endpoint.
if ($endpoint_definition->path == $resource_name) {
$response = t('Services Endpoint "@name" has been setup successfully.', array(
'@name' => $endpoint,
));
drupal_alter('services_endpoint_response', $response);
return $response;
}
return services_error(t('Could not find resource @name.', array(
'@name' => $resource_name,
)), 404);
}
if (!$controller) {
return services_error(t('Could not find the controller.'), 404);
}
// Parse the request data
$arguments = $this
->getControllerArguments($controller, $path, $method);
// Any authentication needed for REST Server must be set in the cookies
$auth_arguments = $_COOKIE;
$formats = $this
->responseFormatters();
// Negotiate response format based on accept-headers if we
// don't have a response format
if (empty($response_format)) {
$mime_candidates = array();
$mime_map = array();
// Add all formatters that accepts raw data, or supports the format model
foreach ($formats as $format => $formatter) {
if (!isset($formatter['model']) || $this
->supportedControllerModel($controller, $formatter)) {
foreach ($formatter['mime types'] as $m) {
$mime_candidates[] = $m;
$mime_map[$m] = $format;
}
}
}
// Get the best matching format, default to json
$response_format = 'json';
if (isset($_SERVER['HTTP_ACCEPT'])) {
$mime = $this
->mimeParse();
$mime_type = $mime
->best_match($mime_candidates, $_SERVER['HTTP_ACCEPT']);
$response_format = $mime_map[$mime_type];
}
}
// Check if we support the response format and determine the mime type
if (empty($mime_type) && isset($formats[$response_format])) {
$formatter = $formats[$response_format];
if (!isset($formatter['model']) || $this
->supportedControllerModel($controller, $formatter)) {
$mime_type = $formatter['mime types'][0];
}
}
if (empty($response_format) || empty($mime_type)) {
return services_error(t('Unknown or unsupported response format.'), 406);
}
// Give the model (if any) a opportunity to alter the arguments.
// This might be needed for the model to ensure that all the required
// information is requested.
if (isset($formatter['model'])) {
$cm =& $controller['models'][$formatter['model']];
if (!isset($cm['arguments'])) {
$cm['arguments'] = array();
}
// Check if any of the model arguments have been overridden
if (isset($cm['allow_overrides'])) {
foreach ($cm['allow_overrides'] as $arg) {
if (isset($_GET[$formatter['model'] . ':' . $arg])) {
$cm['arguments'][$arg] = $_GET[$formatter['model'] . ':' . $arg];
}
}
}
if (isset($cm['class']) && class_exists($cm['class'])) {
if (method_exists($cm['class'], 'alterArguments')) {
call_user_func_array($cm['class'] . '::alterArguments', array(
&$arguments,
$cm['arguments'],
));
}
}
}
try {
$result = services_controller_execute($controller, $arguments);
} catch (ServicesException $e) {
$errors = $this
->handleException($e);
drupal_alter('rest_server_execute_errors', $errors, $controller, $arguments);
$result = $errors;
}
$formatter = $formats[$response_format];
// Set the content type and render output
drupal_set_header('Content-type: ' . $mime_type);
return $this
->renderFormatterView($controller, $formatter, $result);
}