Mercurial > hg > cmmr2012-drupal-site
diff vendor/chi-teck/drupal-code-generator/templates/d8/plugin/rest-resource.twig @ 0:c75dbcec494b
Initial commit from drush-created site
author | Chris Cannam |
---|---|
date | Thu, 05 Jul 2018 14:24:15 +0000 |
parents | |
children | a9cd425dd02b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/chi-teck/drupal-code-generator/templates/d8/plugin/rest-resource.twig Thu Jul 05 14:24:15 2018 +0000 @@ -0,0 +1,306 @@ +<?php + +namespace Drupal\{{ machine_name }}\Plugin\rest\resource; + +use Drupal\Component\Plugin\DependentPluginInterface; +use Drupal\Core\Database\Connection; +use Drupal\rest\ModifiedResourceResponse; +use Drupal\rest\Plugin\ResourceBase; +use Drupal\rest\ResourceResponse; +use Psr\Log\LoggerInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; + +/** + * Represents {{ plugin_label }} records as resources. + * + * @RestResource ( + * id = "{{ plugin_id }}", + * label = @Translation("{{ plugin_label }}"), + * uri_paths = { + * "canonical" = "/api/{{ plugin_id|u2h }}/{id}", + * "https://www.drupal.org/link-relations/create" = "/api/{{ plugin_id|u2h }}" + * } + * ) + * + * @DCG + * This plugin exposes database records as REST resources. In order to enable it + * import the resource configuration into active configuration storage. You may + * find an example of such configuration in the following file: + * core/modules/rest/config/optional/rest.resource.entity.node.yml. + * Alternatively you can make use of REST UI module. + * @see https://www.drupal.org/project/restui + * For accessing Drupal entities through REST interface use + * \Drupal\rest\Plugin\rest\resource\EntityResource plugin. + */ +class {{ class }} extends ResourceBase implements DependentPluginInterface { + + /** + * The database connection. + * + * @var \Drupal\Core\Database\Connection + */ + protected $dbConnection; + + /** + * Constructs a Drupal\rest\Plugin\rest\resource\EntityResource object. + * + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $plugin_id + * The plugin_id for the plugin instance. + * @param mixed $plugin_definition + * The plugin implementation definition. + * @param array $serializer_formats + * The available serialization formats. + * @param \Psr\Log\LoggerInterface $logger + * A logger instance. + * @param \Drupal\Core\Database\Connection $db_connection + * The database connection. + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, array $serializer_formats, LoggerInterface $logger, Connection $db_connection) { + parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger); + $this->dbConnection = $db_connection; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->getParameter('serializer.formats'), + $container->get('logger.factory')->get('rest'), + $container->get('database') + ); + } + + /** + * Responds to GET requests. + * + * @param int $id + * The ID of the record. + * + * @return \Drupal\rest\ResourceResponse + * The response containing the record. + * + * @throws \Symfony\Component\HttpKernel\Exception\HttpException + */ + public function get($id) { + return new ResourceResponse($this->loadRecord($id)); + } + + /** + * Responds to POST requests and saves the new record. + * + * @param mixed $record + * Data to write into the database. + * + * @return \Drupal\rest\ModifiedResourceResponse + * The HTTP response object. + */ + public function post($record) { + + $this->validate($record); + + $id = $this->dbConnection->insert('{{ plugin_id }}') + ->fields($record) + ->execute(); + + $this->logger->notice('New {{ plugin_label|lower }} record has been created.'); + + $created_record = $this->loadRecord($id); + + // Return the newly created record in the response body. + return new ModifiedResourceResponse($created_record, 201); + } + + /** + * Responds to entity PATCH requests. + * + * @param int $id + * The ID of the record. + * @param mixed $record + * Data to write into the database. + * + * @return \Drupal\rest\ModifiedResourceResponse + * The HTTP response object. + */ + public function patch($id, $record) { + $this->validate($record); + return $this->updateRecord($id, $record); + } + + /** + * Responds to entity PUT requests. + * + * @param int $id + * The ID of the record. + * @param mixed $record + * Data to write into the database. + * + * @return \Drupal\rest\ModifiedResourceResponse + * The HTTP response object. + */ + public function put($id, $record) { + + $this->validate($record); + + // Provide default values to make sure the record is completely replaced. + $record += [ + 'title' => '', + 'description' => '', + 'price' => 0, + ]; + + return $this->updateRecord($id, $record); + } + + /** + * Responds to entity DELETE requests. + * + * @param int $id + * The ID of the record. + * + * @return \Drupal\rest\ModifiedResourceResponse + * The HTTP response object. + * + * @throws \Symfony\Component\HttpKernel\Exception\HttpException + */ + public function delete($id) { + + // Make sure the record still exists. + $this->loadRecord($id); + + $this->dbConnection->delete('{{ plugin_id }}') + ->condition('id', $id) + ->execute(); + + $this->logger->notice('{{ plugin_label }} record @id has been deleted.', ['@id' => $id]); + + // Deleted responses have an empty body. + return new ModifiedResourceResponse(NULL, 204); + } + + /** + * {@inheritdoc} + */ + protected function getBaseRoute($canonical_path, $method) { + $route = parent::getBaseRoute($canonical_path, $method); + + // Change ID validation pattern. + if ($method != 'POST') { + $route->setRequirement('id', '\d+'); + } + + return $route; + } + + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + return []; + } + + /** + * {@inheritdoc} + */ + public function routes() { + $collection = parent::routes(); + + // ResourceBase class does not support PUT method by some reason. + $definition = $this->getPluginDefinition(); + $canonical_path = $definition['uri_paths']['canonical']; + $route = $this->getBaseRoute($canonical_path, 'PUT'); + $route->addRequirements(['_content_type_format' => implode('|', $this->serializerFormats)]); + $collection->add('{{ plugin_id }}.PUT', $route); + + return $collection; + } + + /** + * Validates incoming record. + * + * @param mixed $record + * Data to validate. + * + * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException + */ + protected function validate($record) { + if (!is_array($record) || count($record) == 0) { + throw new BadRequestHttpException('No record content received.'); + } + + $allowed_fields = [ + 'title', + 'description', + 'price', + ]; + + if (count(array_diff(array_keys($record), $allowed_fields)) > 0) { + throw new BadRequestHttpException('Record structure is not correct.'); + } + + if (empty($record['title'])) { + throw new BadRequestHttpException('Title is required.'); + } + elseif (isset($record['title']) && strlen($record['title']) > 255) { + throw new BadRequestHttpException('Title is too big.'); + } + // @DCG Add more validation rules here. + } + + /** + * Loads record from database. + * + * @param int $id + * The ID of the record. + * + * @return array + * The database record. + * + * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException + */ + protected function loadRecord($id) { + $record = $this->dbConnection->query('SELECT * FROM {{ '{' }}{{ plugin_id }}{{ '}' }} WHERE id = :id', [':id' => $id])->fetchAssoc(); + if (!$record) { + throw new NotFoundHttpException('The record was not found.'); + } + return $record; + } + + /** + * Updates record. + * + * @param int $id + * The ID of the record. + * @param array $record + * The record to validate. + * + * @return \Drupal\rest\ModifiedResourceResponse + * The HTTP response object. + */ + protected function updateRecord($id, array $record) { + + // Make sure the record already exists. + $this->loadRecord($id); + + $this->validate($record); + + $this->dbConnection->update('{{ plugin_id }}') + ->fields($record) + ->condition('id', $id) + ->execute(); + + $this->logger->notice('{{ plugin_label }} record @id has been updated.', ['@id' => $id]); + + // Return the updated record in the response body. + $updated_record = $this->loadRecord($id); + return new ModifiedResourceResponse($updated_record, 200); + } + +}