161 lines
4.7 KiB
PHP
161 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace Drupal\consumers;
|
|
|
|
use Drupal\Core\Entity\EntityStorageException;
|
|
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
|
use Drupal\Core\Utility\Error;
|
|
use Psr\Log\LoggerAwareTrait;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\RequestStack;
|
|
|
|
/**
|
|
* Extracts the consumer information from the given context.
|
|
*
|
|
* @internal
|
|
*/
|
|
class Negotiator {
|
|
|
|
use LoggerAwareTrait;
|
|
|
|
/**
|
|
* Protected requestStack.
|
|
*
|
|
* @var \Symfony\Component\HttpFoundation\RequestStack
|
|
*/
|
|
protected $requestStack;
|
|
|
|
/**
|
|
* The entity storage.
|
|
*
|
|
* @var \Drupal\Core\Entity\EntityStorageInterface
|
|
*/
|
|
protected $storage;
|
|
|
|
/**
|
|
* The default consumer.
|
|
*
|
|
* @var \Drupal\consumers\Entity\ConsumerInterface
|
|
*/
|
|
protected $defaultConsumer;
|
|
|
|
/**
|
|
* Instantiates a new Negotiator object.
|
|
*/
|
|
public function __construct(RequestStack $request_stack, LoggerInterface $logger) {
|
|
$this->requestStack = $request_stack;
|
|
$this->logger = $logger;
|
|
}
|
|
|
|
/**
|
|
* Obtains the consumer from the request.
|
|
*
|
|
* @param \Symfony\Component\HttpFoundation\Request $request
|
|
* The request.
|
|
*
|
|
* @return \Drupal\consumers\Entity\ConsumerInterface|null
|
|
* The consumer.
|
|
*
|
|
* @throws \Drupal\consumers\MissingConsumer
|
|
*/
|
|
protected function doNegotiateFromRequest(Request $request) {
|
|
// There are several ways to negotiate the consumer:
|
|
// 1. Via a custom header.
|
|
$consumer_id = $request->headers->get('X-Consumer-ID');
|
|
if (!$consumer_id) {
|
|
// 2. Via a query string parameter.
|
|
$consumer_id = $request->query->get('consumerId');
|
|
if (!$consumer_id && $request->query->has('_consumer_id')) {
|
|
$this->logger->warning('The "_consumer_id" query string parameter is deprecated and it will be removed in the next major version of the module, please use "consumerId" instead.');
|
|
$consumer_id = $request->query->get('_consumer_id');
|
|
}
|
|
}
|
|
if ($consumer_id) {
|
|
try {
|
|
$results = $this->storage->loadByProperties(['client_id' => $consumer_id]);
|
|
/** @var \Drupal\consumers\Entity\ConsumerInterface $consumer */
|
|
$consumer = !empty($results) ? reset($results) : $results;
|
|
}
|
|
catch (EntityStorageException $exception) {
|
|
// Backwards compatibility of error logging. See
|
|
// https://www.drupal.org/node/2932520. This can be removed when we no
|
|
// longer support Drupal > 10.1.
|
|
if (version_compare(\Drupal::VERSION, '10.1', '>=')) {
|
|
$logger = \Drupal::logger('consumers');
|
|
Error::logException($logger, $exception);
|
|
}
|
|
else {
|
|
// @phpstan-ignore-next-line
|
|
watchdog_exception('consumers', $exception);
|
|
}
|
|
}
|
|
}
|
|
if (empty($consumer)) {
|
|
$consumer = $this->loadDefaultConsumer();
|
|
}
|
|
return $consumer;
|
|
}
|
|
|
|
/**
|
|
* Obtains the consumer from the request.
|
|
*
|
|
* @param \Symfony\Component\HttpFoundation\Request|null $request
|
|
* The request object to inspect for a consumer. Set to NULL to use the
|
|
* current request.
|
|
*
|
|
* @return \Drupal\consumers\Entity\ConsumerInterface|null
|
|
* The consumer.
|
|
*
|
|
* @throws \Drupal\consumers\MissingConsumer
|
|
*/
|
|
public function negotiateFromRequest(Request $request = NULL) {
|
|
// If the request is not provided, use the request from the stack.
|
|
$request = $request ? $request : $this->requestStack->getCurrentRequest();
|
|
$consumer = $this->doNegotiateFromRequest($request);
|
|
$request->attributes->set('consumer_id', $consumer->getClientId());
|
|
return $consumer;
|
|
}
|
|
|
|
/**
|
|
* Finds and loads the default consumer.
|
|
*
|
|
* @return \Drupal\consumers\Entity\ConsumerInterface
|
|
* The consumer entity.
|
|
*
|
|
* @throws \Drupal\consumers\MissingConsumer
|
|
*/
|
|
protected function loadDefaultConsumer() {
|
|
if (!empty($this->defaultConsumer)) {
|
|
return $this->defaultConsumer;
|
|
}
|
|
|
|
// Find the default consumer.
|
|
$results = $this->storage->getQuery()
|
|
->accessCheck(TRUE)
|
|
->condition('is_default', TRUE)
|
|
->execute();
|
|
$consumer_id = reset($results);
|
|
if (!$consumer_id) {
|
|
// Throw if there is no default consumer.
|
|
throw new MissingConsumer('Unable to find the default consumer.');
|
|
}
|
|
$this->defaultConsumer = $this->storage->load($consumer_id);
|
|
|
|
return $this->defaultConsumer;
|
|
}
|
|
|
|
/**
|
|
* Sets the storage from the entity type manager.
|
|
*
|
|
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
|
* The entity type manager.
|
|
*
|
|
* @throws \Drupal\Component\Plugin\Exception\PluginException
|
|
*/
|
|
public function setEntityStorage(EntityTypeManagerInterface $entity_type_manager) {
|
|
$this->storage = $entity_type_manager->getStorage('consumer');
|
|
}
|
|
|
|
}
|