OpenXE/classes/Modules/Hubspot/Scheduler/HubspotPullEngagementsTask.php
2021-05-21 08:49:41 +02:00

290 lines
8.9 KiB
PHP

<?php
declare(strict_types=1);
namespace Xentral\Modules\Hubspot\Scheduler;
use ArrayObject;
use Xentral\Components\Database\Database;
use Xentral\Modules\Hubspot\Exception\HubspotConfigurationServiceException;
use Xentral\Modules\Hubspot\Exception\HubspotException;
use Xentral\Modules\Hubspot\Exception\MetaException;
use Xentral\Modules\Hubspot\HubspotConfigurationService;
use Xentral\Modules\Hubspot\HubspotContactGateway;
use Xentral\Modules\Hubspot\HubspotEngagementService;
use Xentral\Modules\Hubspot\HubspotEventService;
use Xentral\Modules\Hubspot\HubspotMetaService;
use Xentral\Modules\SubscriptionCycle\Scheduler\TaskMutexServiceInterface;
final class HubspotPullEngagementsTask implements HubspotSchedulerTaskInterface
{
/** @var int[] $itemsCount */
private $itemsCount = ['count' => 100];
/** @var Database $db */
private $db;
/** @var HubspotEngagementService $engagementsService */
private $engagementsService;
/** @var HubspotMetaService $meta */
private $meta;
/** @var HubspotConfigurationService $configuration */
private $configuration;
/** @var HubspotEventService $event */
private $event;
/** @var HubspotContactGateway $contactGateway */
private $contactGateway;
/** @var TaskMutexServiceInterface $taskMutexService */
private $taskMutexService;
/**
* @param Database $db
* @param HubspotEngagementService $engagementService
* @param HubspotMetaService $metaService
* @param HubspotConfigurationService $configuration
* @param HubspotEventService $eventService
* @param HubspotContactGateway $contactGateway
* @param TaskMutexServiceInterface $taskMutexService
*/
public function __construct(
Database $db,
HubspotEngagementService $engagementService,
HubspotMetaService $metaService,
HubspotConfigurationService $configuration,
HubspotEventService $eventService,
HubspotContactGateway $contactGateway,
TaskMutexServiceInterface $taskMutexService
) {
$this->db = $db;
$this->engagementsService = $engagementService;
$this->configuration = $configuration;
$this->meta = $metaService;
$this->event = $eventService;
$this->contactGateway = $contactGateway;
$this->taskMutexService = $taskMutexService;
}
/**
* @throws HubspotException
*
* @return void
*/
public function execute(): void
{
if ($this->taskMutexService->isTaskInstanceRunning('hubspot_pull_engagements')) {
return;
}
$this->taskMutexService->setMutex('hubspot_pull_engagements');
try {
$settings = $this->configuration->getSettings();
} catch (HubspotConfigurationServiceException $e) {
return;
}
if (empty($settings['hs_sync_engagements'])) {
return;
}
$this->recursiveExecute();
}
/**
* @param array $option
*
* @throws HubspotException
*
* @return void
*/
private function recursiveExecute(array $option = []): void
{
$remainingData = $this->pull($option);
if (!empty($remainingData['has_more'])) {
unset($remainingData['has_more']);
$this->recursiveExecute($remainingData);
}
}
/**
* @param array $options
*
* @throws HubspotException
*
* @return array|null
*/
private function pull(array $options = []): ?array
{
$options = array_merge($options, $this->itemsCount);
$metaInfo = $this->meta->setName('recent_engagements')->get();
$requestData = [];
if (array_key_exists('since', $metaInfo)) {
$requestData['since'] = $metaInfo['since'];
}
if (array_key_exists('offset', $metaInfo)) {
$requestData['offset'] = $metaInfo['offset'];
}
$options = array_merge($options, $requestData);
$response = $this->engagementsService->getRecentEngagements($options);
if ($response->getStatusCode() !== 200) {
return null;
}
$data = $response->getJson();
$offSet = array_key_exists('offset', $data) ? $data['offset'] : 0;
$hasMore = array_key_exists('hasMore', $data) ? $data['hasMore'] : false;
$total = array_key_exists('total', $data) ? $data['total'] : 0;
$since = array_key_exists('since', $data) ? $data['since'] : time() * 1000;
if ($total === 0 || !array_key_exists('results', $data)) {
return null;
}
$engagements = $data['results'];
foreach ($engagements as $engagement) {
$engagementData = $engagement['engagement'];
// ONLY TYPE NOTE IS CURRENTLY ALLOWED
if ($engagementData['type'] !== 'NOTE') {
continue;
}
$engagementId = $engagementData['id'];
$engagementAssociations = $engagement['associations'];
$metadata = $engagement['metadata'];
$body = $metadata['body'];
$companyIds = null;
$contactIds = null;
if ($this->engagementExists($engagementId)) {
continue;
}
foreach ($engagementAssociations as $intended => $values) {
if (!is_string($intended)) {
continue;
}
if ($intended === 'companyIds') {
$companyIds = $values;
}
if ($intended === 'contactIds') {
$contactIds = $values;
}
}
if (empty($companyIds) && empty($contactIds)) {
continue;
}
$intendedIds = array_merge($companyIds, $contactIds);
foreach ($intendedIds as $intendedId) {
$noteId = $this->addNote($intendedId, $body);
if (empty($noteId)) {
continue;
}
$mapping = $this->contactGateway->getMappingByHubspotId($intendedId, null);
if (empty($mapping)) {
continue;
}
$addressId = $mapping['address_id'];
$this->db->perform(
'INSERT INTO `hubspot_contacts` (`hs_contact_id`, `created_at`, `address_id`, `type`)
VALUES (:id, NOW(), :aid, :type)',
['id' => $engagementId, 'aid' => $noteId, 'type' => 'note']
);
$eventItem = 'Adresse';
$eventMsg = sprintf(
'Neue Notiz vom Hubspot hinzugef&uuml;gt ins Xentral f&uuml;r (<a href="/index.php?module=adresse&action=edit&id=%d">%s</a>) importiert.',
$addressId,
$eventItem
);
$this->event->add($eventMsg);
}
}
$remainingData = ['offset' => $offSet, 'since' => $since];
try {
$this->meta->setName('recent_engagements')->save($remainingData);
} catch (MetaException $e) {
$this->event->add($e->getMessage());
}
$remainingData['has_more'] = $hasMore;
return $remainingData;
}
public function cleanup()
{
$this->taskMutexService->setMutex('hubspot_pull_engagements', false);
}
public function beforeScheduleAction(ArrayObject $args)
{
}
public function afterScheduleAction(ArrayObject $args)
{
}
/**
* @param int $hubspotContactId
* @param string $body
*
* @return int
*/
private function addNote(int $hubspotContactId, string $body): int
{
$mapping = $this->contactGateway->getMappingByHubspotId($hubspotContactId, null);
if (empty($mapping)) {
return 0;
}
$sql = 'INSERT INTO `dokumente` (
`adresse_to`,
`adresse_from`,
`typ`,
`betreff`,
`content`,
`datum`,
`uhrzeit`,
`created`,
`bearbeiter`)
VALUES (:address, 1, :type, :object, :body, :date, :time, NOW(), :editor)';
$this->db->perform(
$sql,
[
'address' => $mapping['address_id'],
'type' => 'notiz',
'object' => 'Hubspot note',
'body' => $body,
'date' => date('Y-m-d'),
'time' => date('H:i:s'),
'editor' => 'HubspotModule',
]
);
return $this->db->lastInsertId();
}
/**
* @param int $engagementId
*
* @return bool
*/
private function engagementExists(int $engagementId) : bool
{
return $this->contactGateway->hubspotContactExists($engagementId, ['note']);
}
}