Skip to content

Instantly share code, notes, and snippets.

@clrockwell
Created June 27, 2018 20:53
Show Gist options
  • Save clrockwell/d41e742da6bfca2836697ddfeb90c5a6 to your computer and use it in GitHub Desktop.
Save clrockwell/d41e742da6bfca2836697ddfeb90c5a6 to your computer and use it in GitHub Desktop.
Allow GETing and POSTing D8 order comments
<?php
namespace Drupal\scholarrx_api\Plugin\rest\resource;
use Drupal\commerce_log\Entity\Log;
use Drupal\commerce_order\Entity\Order;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\openid_connect\Authmap;
use Drupal\rest\Annotation\RestResource;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
/**
* Provides a resource to get view modes by entity and bundle.
*
* @RestResource(
* id = "handle_order_comments",
* label = @Translation("Handle Order comments"),
* uri_paths = {
* "canonical" = "/api/orders/{order_id}/comments",
* "https://www.drupal.org/link-relations/create" = "/api/orders/{order_id}/comments"
* }
* )
*/
class OrderComments extends ResourceBase {
/**
* A current user instance.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* @var \Drupal\openid_connect\Authmap
*/
protected $authmap;
/**
* Constructs a new HandleOrderComments 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\Session\AccountProxyInterface $current_user
* A current user instance.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
array $serializer_formats,
LoggerInterface $logger,
AccountProxyInterface $current_user,
EntityTypeManagerInterface $entityTypeManager,
Authmap $authmap) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);
$this->currentUser = $current_user;
$this->entityTypeManager = $entityTypeManager;
$this->authmap = $authmap;
}
/**
* {@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('scholarrx_api'),
$container->get('current_user'),
$container->get('entity_type.manager'),
$container->get('openid_connect.authmap')
);
}
/**
* Responds to GET requests.
*
* Returns a list of comments for an order.
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
* Throws exception expected.
*/
public function get($order_id) {
\Drupal::service('page_cache_kill_switch')->trigger();
if ($order_id == '') {
throw new BadRequestHttpException('ORDER ID is required');
}
/** @var Order $order */
$order = $this->entityTypeManager->getStorage('commerce_order')
->load($order_id);
$this->assertOrder($order);
$comments = $this->entityTypeManager->getStorage('commerce_log')
->loadMultipleByEntity($order);
$results = array();
/** @var Log $comment */
foreach ($comments as $comment) {
$accounts = $this->authmap->getConnectedAccounts($comment->getUser());
if (isset($accounts['generic'])) {
$sub = $accounts['generic'];
}
else {
$sub = '0';
}
$result['user'] = $sub;
$result['timestamp'] = $comment->getCreatedTime();
$view_builder = \Drupal::entityTypeManager()->getViewBuilder('commerce_log');
$build = $view_builder->view($comment);
/** @var Renderer $renderer */
$renderer = \Drupal::service('renderer');
$result['comment'] = strip_tags($renderer->renderPlain($build));
$results[] = $result;
}
// You must implement the logic of your REST Resource here.
// Use current user after pass authentication to validate access.
if (!$this->currentUser->hasPermission('access content')) {
throw new AccessDeniedHttpException();
}
$response = new ResourceResponse($results);
$response->addCacheableDependency($results);
return new ResourceResponse($results);
}
/**
* Responds to POST requests.
*
* @param Request $request
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
* Throws exception expected.
*/
public function post($order_id, $unknown = '', Request $request) {
$content = Json::decode($request->getContent());
$this->assertComment($content);
$comment = $content['comment'];
if (isset($content['userId'])) {
/** @var AccountInterface $user */
$user = $this->authmap->userLoadBySub($content['userId'], 'generic');
// This user doesn't have an eCommerce account with their sub
if (!$user && $content['userEmail']) {
// Does the user have an account?
$user = user_load_by_mail($content['userEmail']);
if (!$user) {
// If we have an email address create the account.
$user = openid_connect_create_user($content['userId'], [
'email' => $content['userEmail'],
],
'generic');
}
if (!$user) {
// Default to the customerservice user.
$user = user_load_by_name('customerservice');
}
}
}
/** @var Order $order */
$order = $this->entityTypeManager->getStorage('commerce_order')
->load($order_id);
$this->assertOrder($order);
$this->logCommentToOrder($comment, $order, $user);
return new ResourceResponse("Comment added successfully.");
}
protected function logCommentToOrder($comment, $order, $user) {
$log = $this->entityTypeManager->getStorage('commerce_log')->generate($order, 'admin_comment', [
'comment' => $comment,
]);
if ($user && is_object($user)) {
$log->uid = $user->id();
}
$log->save();
}
protected function assertComment($content) {
if (!$content['comment']) {
throw new BadRequestHttpException('A comment must be specified.');
}
}
protected function assertOrder($order) {
if (!$order || !$order instanceof Order) {
throw new BadRequestHttpException('No order found');
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment