Created
June 27, 2018 20:53
-
-
Save clrockwell/d41e742da6bfca2836697ddfeb90c5a6 to your computer and use it in GitHub Desktop.
Allow GETing and POSTing D8 order comments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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