xero-8.x-2.x-dev/src/XeroClientFactory.php
src/XeroClientFactory.php
<?php
namespace Drupal\xero;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Utility\Error;
use Drupal\xero\Exception\XeroInvalidConfigurationException;
use GuzzleHttp\ClientInterface;
use Radcliffe\Xero\XeroClient;
/**
* Xero client factory class.
*/
class XeroClientFactory {
/**
* Return a configured XeroClient object.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The configuration factory.
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
* The logger factory.
* @param \Drupal\Core\Session\AccountProxyInterface $account
* The current_user service.
* @param \Drupal\Xero\XeroTokenManagerInterface $tokenManager
* The xero.token_manager service.
* @param \Drupal\Component\Datetime\TimeInterface $time
* The datetime.time service.
* @param \GuzzleHttp\ClientInterface|null $httpClient
* A standard http_client to use for XeroProvider.
*
* @return \Radcliffe\Xero\XeroClientInterface
* A Guzzle HTTP client configured to use the Xero API.
*/
public function get(ConfigFactoryInterface $config_factory, LoggerChannelFactoryInterface $logger_factory, AccountProxyInterface $account, XeroTokenManagerInterface $tokenManager, TimeInterface $time, ?ClientInterface $httpClient = NULL) {
$config = $config_factory->get('xero.settings');
$id = $config->get('oauth.consumer_key');
$secret = $config->get('oauth.consumer_secret');
$uri = $config->get('oauth.redirect_uri');
$grant = NULL;
$token = '';
$data = FALSE;
$options = [];
$isGlobal = FALSE;
try {
// Retrieve the global tokens from the xero key_value store.
$isGlobal = !$tokenManager->hasUserToken($account);
$data = $tokenManager->getToken($account, $isGlobal);
if ($data && !$data->hasExpired()) {
// Use the unexpired access token.
$token = $data->getToken();
}
elseif ($data && $data->getRefreshToken() !== NULL) {
// Use the refresh token to get a new access token.
$grant = 'refresh_token';
$token = $data->getRefreshToken();
}
else {
throw new XeroInvalidConfigurationException('No access token or refresh token available. Application needs to be re-authorized.');
}
$collaborators = is_null($httpClient) ? [] : [
'httpClient' => $httpClient,
];
$tenant = $config->get('defaults.tenant');
if ($tenant) {
$options['tenant'] = $tenant;
}
$client = XeroClient::createFromToken($id, $secret, $token, $grant, 'accounting', $options, $collaborators, $uri);
if ($grant === 'refresh_token') {
// Sets the new access token into the key store.
$newToken = $client->getRefreshedToken();
$setAccount = $isGlobal ? NULL : $account;
// @todo https://github.com/mradcliffe/xeroclient/issues/18
$tokenManager->setToken($newToken, $setAccount, $client->getTenantIds());
}
return $client;
}
catch (\Throwable $e) {
$message = "Error getting Xero client. ";
$variables = Error::decodeException($e);
if ($data) {
$variables['exception'] = $e;
$variables['%tenant'] = $tenant ?? 'NULL';
$variables['@token_type'] = $isGlobal ? 'global' : 'user';
if ($grant === 'refresh_token') {
$message .= "Using @token_type refresh token to get a new @token_type access token for %tenant.";
}
elseif (!$data->hasExpired()) {
$message .= "Using unexpired @token_type access token for %tenant.";
}
}
$logger = $logger_factory->get('xero');
$logger->error($message . '. %type: @message in %function (line %line of %file', $variables);
// This will fail due to missing auth_token for any subsequent requests,
// but will still attempt to make the request.
return XeroClient::createFromConfig([
'base_uri' => 'https://api.xero.com/api.xro/2.0/',
]);
}
}
}
