View source
<?php
namespace Drupal\hubspot;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\EmailValidatorInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Mail\MailManagerInterface;
use Drupal\Core\State\StateInterface;
use Drupal\Core\Url;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use GuzzleHttp\RequestOptions;
use Symfony\Component\HttpFoundation\RequestStack;
class Hubspot {
use StringTranslationTrait;
protected $state;
protected $httpClient;
protected $config;
protected $logger;
protected $mailManager;
protected $hubspotForms;
private $currentRequest;
private $emailValidator;
public function __construct(StateInterface $state, LoggerChannelFactoryInterface $logger_factory, ConfigFactoryInterface $config_factory, ClientInterface $httpClient, MailManagerInterface $mailManager, RequestStack $requestStack, EmailValidatorInterface $emailValidator) {
$this->state = $state;
$this->httpClient = $httpClient;
$this->config = $config_factory
->get('hubspot.settings');
$this->logger = $logger_factory
->get('hubspot');
$this->mailManager = $mailManager;
$this->currentRequest = $requestStack
->getCurrentRequest();
$this->emailValidator = $emailValidator;
}
public function isConfigured() : bool {
return !empty($this->state
->get('hubspot.hubspot_refresh_token'));
}
public function authorize(string $code) {
$response = $this->httpClient
->post('https://api.hubapi.com/oauth/v1/token', [
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8',
],
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => $this->config
->get('hubspot_client_id'),
'client_secret' => $this->config
->get('hubspot_client_secret'),
'redirect_uri' => Url::fromRoute('hubspot.oauth_connect', [], [
'absolute' => TRUE,
])
->toString(),
'code' => $code,
],
]);
$data = Json::decode($response
->getBody()
->getContents());
$this->state
->set('hubspot.hubspot_access_token', $data['access_token']);
$this->state
->set('hubspot.hubspot_refresh_token', $data['refresh_token']);
$this->state
->set('hubspot.hubspot_expires_in', $data['expires_in'] + $this->currentRequest->server
->get('REQUEST_TIME'));
}
public function getHubspotForms() : array {
static $hubspot_forms;
if (!isset($hubspot_forms)) {
$api = 'https://api.hubapi.com/forms/v2/forms';
$url = Url::fromUri($api)
->toString();
$response = $this
->request('GET', $url);
if (isset($response['error'])) {
return [];
}
else {
$hubspot_forms = $response['value'] ?? [];
}
}
return $hubspot_forms;
}
public function request(string $method, string $url, array $options = []) : array {
$access_token = $this->state
->get('hubspot.hubspot_access_token');
if (empty($access_token)) {
return [
'error' => $this
->t('This site is not connected to a HubSpot Account.'),
];
}
$options += [
'headers' => [
'Authorization' => 'Bearer ' . $access_token,
],
];
try {
$response = $this->httpClient
->request($method, $url, $options);
} catch (RequestException $e) {
global $base_url;
$refresh_token = $this->state
->get('hubspot.hubspot_refresh_token');
try {
$reauth = $this->httpClient
->post('https://api.hubapi.com/oauth/v1/token', [
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8',
],
'form_params' => [
'grant_type' => 'refresh_token',
'client_id' => $this->config
->get('hubspot_client_id'),
'client_secret' => $this->config
->get('hubspot_client_secret'),
'redirect_uri' => $base_url . Url::fromRoute('hubspot.oauth_connect')
->toString(),
'refresh_token' => $refresh_token,
],
])
->getBody();
$data = Json::decode($reauth);
$this->state
->set('hubspot.hubspot_access_token', $data['access_token']);
$this->state
->set('hubspot.hubspot_refresh_token', $data['refresh_token']);
$this->state
->set('hubspot.hubspot_expires_in', $data['expires_in'] + $this->currentRequest->server
->get('REQUEST_TIME'));
$response = $this->httpClient
->request($method, $url, $options);
} catch (RequestException $e) {
$this->logger
->error($this
->t('Unable to execute request: %message', [
'%message' => $e
->getMessage(),
]));
return [
'error' => $e
->getMessage(),
];
}
}
$data = $response
->getBody()
->getContents();
return [
'value' => Json::decode($data),
'response' => $response,
];
}
public function submitHubspotForm(string $form_guid, array $form_field_values, array $context = []) : array {
array_walk($form_field_values, function (&$value) {
if (is_string($value) && $this->emailValidator
->isValid($value)) {
$value = str_replace('%40', '@', urlencode($value));
}
if (is_array($value)) {
$value = implode(';', $value);
}
});
$portal_id = $this->config
->get('hubspot_portal_id');
$api = 'https://forms.hubspot.com/uploads/form/v2/' . $portal_id . '/' . $form_guid;
$url = Url::fromUri($api)
->toString();
$hs_context = [
'hutk' => $this->currentRequest->cookies
->get('hubspotutk') ?? '',
'ipAddress' => $this->currentRequest
->getClientIp(),
'pageName' => isset($context['pageName']) ? $context['pageName'] : '',
'pageUrl' => $this->currentRequest->headers
->get('referer'),
];
$hs_context = array_merge($hs_context, $context);
$request_options = [
RequestOptions::HEADERS => [
'Content-Type' => 'application/x-www-form-urlencoded',
],
RequestOptions::FORM_PARAMS => $form_field_values + [
'hs_context' => Json::encode($hs_context),
],
];
return $this
->request('POST', $url, $request_options);
}
public function hubspotGetRecent(int $n = 5) : array {
$api = 'https://api.hubapi.com/contacts/v1/lists/recently_updated/contacts/recent';
$options = [
'query' => [
'count' => $n,
],
];
$url = Url::fromUri($api, $options)
->toString();
$result = $this
->request('GET', $url);
$response = $result['response'];
return [
'Data' => $result['value'],
'Error' => isset($response->error) ? $response->error : '',
'HTTPCode' => $response
->getStatusCode(),
];
}
}