diff --git a/core/modules/rest/lib/Drupal/rest/Plugin/ResourceBase.php b/core/modules/rest/lib/Drupal/rest/Plugin/ResourceBase.php index 8ca8fcd..962af71 100644 --- a/core/modules/rest/lib/Drupal/rest/Plugin/ResourceBase.php +++ b/core/modules/rest/lib/Drupal/rest/Plugin/ResourceBase.php @@ -17,13 +17,6 @@ abstract class ResourceBase extends PluginBase { /** - * Holds all predefined HTTP methods and their configuration. - * - * @var array - */ - protected $requestMethods; - - /** * Provides an array of permissions suitable for hook_permission(). * * Every plugin operation method gets its own user permission. Example: @@ -36,7 +29,7 @@ public function permissions() { $permissions = array(); $definition = $this->getDefinition(); - foreach ($this->requestMethods() as $method => $settings) { + foreach ($this->requestMethods() as $method) { $lowered_method = strtolower($method); // Only expose permissions where the HTTP request method exists on the // plugin. @@ -62,7 +55,7 @@ public function routes() { $collection = new RouteCollection(); $methods = $this->requestMethods(); - foreach ($methods as $method => $settings) { + foreach ($methods as $method) { // Only expose routes where the HTTP request method exists on the plugin. if (method_exists($this, strtolower($method))) { $prefix = strtr($this->plugin_id, ':', '/'); @@ -90,73 +83,22 @@ public function routes() { * Provides predefined HTTP request methods. * * Plugins can override this method to provide additional custom request - * methods or to alter the semantics. - * - * @param string $method - * Optional: a specific request method to return setting information for. + * methods. * * @return array - * An array with HTTP methods as keys and value arrays with the following - * key/value pairs: - * - success_code: an integer used for the HTTP response code on success. - * - incoming_data: a boolean to indicate that incoming data has to be - * de-serialized. - * - outgoing_data: a boolean to indicate that outgoing data has to be - * serialized. + * The list of allowed HTTP request method strings. */ - public function requestMethods($method = NULL) { - if ($this->requestMethods == NULL) { - $this->requestMethods = array( - 'HEAD' => array( - 'success_code' => 200, - 'incoming_data' => FALSE, - 'outgoing_data' => FALSE, - ), - 'GET' => array( - 'success_code' => 200, - 'incoming_data' => FALSE, - 'outgoing_data' => TRUE, - ), - 'POST' => array( - 'success_code' => 201, - 'incoming_data' => TRUE, - 'outgoing_data' => FALSE, - ), - 'PUT' => array( - 'success_code' => 200, - 'incoming_data' => TRUE, - 'outgoing_data' => FALSE, - ), - 'DELETE' => array( - 'success_code' => 204, - 'incoming_data' => FALSE, - 'outgoing_data' => FALSE, - ), - 'TRACE' => array( - 'success_code' => 200, - 'incoming_data' => FALSE, - 'outgoing_data' => FALSE, - ), - 'OPTIONS' => array( - 'success_code' => 200, - 'incoming_data' => FALSE, - 'outgoing_data' => FALSE, - ), - 'CONNECT' => array( - 'success_code' => 200, - 'incoming_data' => FALSE, - 'outgoing_data' => FALSE, - ), - 'PATCH' => array( - 'success_code' => 200, - 'incoming_data' => TRUE, - 'outgoing_data' => FALSE, - ), - ); - } - if ($method) { - return $this->requestMethods[$method]; - } - return $this->requestMethods; + protected function requestMethods() { + return drupal_map_assoc(array( + 'HEAD', + 'GET', + 'POST', + 'PUT', + 'DELETE', + 'TRACE', + 'OPTIONS', + 'CONNECT', + 'PATCH', + )); } } diff --git a/core/modules/rest/lib/Drupal/rest/Plugin/rest/resource/DBLogResource.php b/core/modules/rest/lib/Drupal/rest/Plugin/rest/resource/DBLogResource.php index 71c3d1c..7ec6b3e 100644 --- a/core/modules/rest/lib/Drupal/rest/Plugin/rest/resource/DBLogResource.php +++ b/core/modules/rest/lib/Drupal/rest/Plugin/rest/resource/DBLogResource.php @@ -7,9 +7,11 @@ namespace Drupal\rest\Plugin\rest\resource; -use Drupal\rest\Plugin\ResourceBase; use Drupal\Core\Annotation\Plugin; use Drupal\Core\Annotation\Translation; +use Drupal\rest\Plugin\ResourceBase; +use Drupal\rest\ResourceResponse; + use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** @@ -38,8 +40,8 @@ public function routes() { * * Returns a watchdog log entry for the specified ID. * - * @return object - * The databse row loaded as stdClass object. + * @return \Drupal\rest\ResourceResponse + * The response containing the log entry. * * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ @@ -50,10 +52,17 @@ public function get($id = NULL) { ->fields('w') ->execute() ->fetchAll(); - if (empty($result)) { - throw new NotFoundHttpException('Not Found'); + $result = db_query("SELECT * FROM {watchdog} WHERE wid = :wid", array(':wid' => $id)) + ->fetchObject(); + if (!empty($result)) { + // Serialization is done here, so we indicate with NULL that there is no + // subsequent serialization necessary. + $response = new ResourceResponse(NULL, 200, array('Content-Type' => 'application/json')); + // @todo remove hard coded format here. + $response->setContent(drupal_json_encode($result)); + return $response; } - return $result[0]; } + throw new NotFoundHttpException('Not Found'); } } diff --git a/core/modules/rest/lib/Drupal/rest/Plugin/rest/resource/EntityResource.php b/core/modules/rest/lib/Drupal/rest/Plugin/rest/resource/EntityResource.php index a28ae07..689fd84 100644 --- a/core/modules/rest/lib/Drupal/rest/Plugin/rest/resource/EntityResource.php +++ b/core/modules/rest/lib/Drupal/rest/Plugin/rest/resource/EntityResource.php @@ -11,7 +11,7 @@ use Drupal\Core\Annotation\Translation; use Drupal\Core\Entity\EntityStorageException; use Drupal\rest\Plugin\ResourceBase; -use Symfony\Component\HttpFoundation\Response; +use Drupal\rest\ResourceResponse; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -32,8 +32,8 @@ class EntityResource extends ResourceBase { * @param mixed $id * The entity ID. * - * @return \Drupal\Core\Entity\EntityInterface - * The loaded entity. + * @return \Drupal\rest\ResourceResponse + * The response containing the loaded entity. * * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ @@ -41,7 +41,7 @@ public function get($id) { $definition = $this->getDefinition(); $entity = entity_load($definition['entity_type'], $id); if ($entity) { - return $entity; + return new ResourceResponse($entity); } throw new NotFoundHttpException(t('Entity with ID @id not found', array('@id' => $id))); } @@ -52,6 +52,9 @@ public function get($id) { * @param mixed $id * The entity ID. * + * @return \Drupal\rest\ResourceResponse + * The HTTP response object. + * * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ public function delete($id) { @@ -60,13 +63,13 @@ public function delete($id) { if ($entity) { try { $entity->delete(); + // Delete responses have an empty body. + return new ResourceResponse(NULL, 204); } catch (EntityStorageException $e) { throw new HttpException(500, 'Internal Server Error', $e); } } - else { - throw new NotFoundHttpException(t('Entity with ID @id not found', array('@id' => $id))); - } + throw new NotFoundHttpException(t('Entity with ID @id not found', array('@id' => $id))); } } diff --git a/core/modules/rest/lib/Drupal/rest/RequestHandler.php b/core/modules/rest/lib/Drupal/rest/RequestHandler.php index 1dbd81a..a45ebf8 100644 --- a/core/modules/rest/lib/Drupal/rest/RequestHandler.php +++ b/core/modules/rest/lib/Drupal/rest/RequestHandler.php @@ -7,7 +7,6 @@ namespace Drupal\rest; -use Drupal\Core\Entity\EntityNG; use Symfony\Component\DependencyInjection\ContainerAware; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -34,41 +33,31 @@ class RequestHandler extends ContainerAware { * '_plugin' property of route object. */ public function handle($plugin, Request $request, $id = NULL) { - $method = $request->getMethod(); - $lower_method = strtolower($method); - if (user_access("restful $lower_method $plugin")) { + $method = strtolower($request->getMethod()); + if (user_access("restful $method $plugin")) { $resource = $this->container ->get('plugin.manager.rest') ->getInstance(array('id' => $plugin)); + $received = $request->getContent(); // @todo De-serialization should happen here if the request is supposed // to carry incoming data. - $settings = $resource->requestMethods($method); try { - $data = $resource->{$lower_method}($id); + $response = $resource->{$method}($id, $received); } catch (HttpException $e) { return new Response($e->getMessage(), $e->getStatusCode(), $e->getHeaders()); } - // If the plugin returns response objects itself we pass them through. - if ($data instanceof Response) { - return $data; + $data = $response->getResponseData(); + if ($data != NULL) { + // Serialize the response data. + $serializer = $this->container->get('serializer'); + // @todo Replace the format here with something we get from the HTTP + // Accept headers. See http://drupal.org/node/1833440 + $output = $serializer->serialize($data, 'drupal_jsonld'); + $response->setContent($output); + $response->headers->set('Content-Type', 'application/ld+json'); } - // If there is no response body data to return we can send a response - // immediately. - if (empty($settings['outgoing_data'])) { - return new Response('', $settings['success_code']); - } - // Otherwise we serialize the data. - $serializer = $this->container->get('serializer'); - // Convert object to array as normalizer does not support - // non EntityNG objects. - if (is_object($data) && !$data instanceof EntityNG) { - $data = (array) $data; - } - // @todo Replace the format here with something we get from the HTTP - // Accept headers. See http://drupal.org/node/1833440 - $output = $serializer->serialize($data, 'drupal_jsonld'); - return new Response($output, $settings['success_code'], array('Content-Type' => 'application/ld+json')); + return $response; } return new Response('Access Denied', 403); } diff --git a/core/modules/rest/lib/Drupal/rest/ResourceResponse.php b/core/modules/rest/lib/Drupal/rest/ResourceResponse.php new file mode 100644 index 0000000..a93f25e --- /dev/null +++ b/core/modules/rest/lib/Drupal/rest/ResourceResponse.php @@ -0,0 +1,48 @@ +responseData = $data; + parent::__construct('', $status, $headers); + } + + /** + * Returns response data that should be serialized. + * + * @return mixed + * Response data that should be serialized. + */ + public function getResponseData() { + return $this->responseData; + } +}