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); } }