Spaces:
No application file
No application file
declare(strict_types=1); | |
namespace Mautic\IntegrationsBundle\Sync\Helper; | |
use Doctrine\DBAL\Connection; | |
use Mautic\IntegrationsBundle\Sync\SyncDataExchange\MauticSyncDataExchange; | |
class SyncDateHelper | |
{ | |
private ?\DateTimeInterface $syncFromDateTime = null; | |
private ?\DateTimeInterface $syncToDateTime = null; | |
private ?\DateTimeImmutable $syncDateTime = null; | |
/** | |
* @var \DateTimeInterface[] | |
*/ | |
private array $lastObjectSyncDates = []; | |
private ?\DateTimeInterface $internalSyncStartDateTime = null; | |
public function __construct( | |
private Connection $connection | |
) { | |
} | |
public function setSyncDateTimes(?\DateTimeInterface $fromDateTime = null, ?\DateTimeInterface $toDateTime = null): void | |
{ | |
$this->syncFromDateTime = $fromDateTime; | |
$this->syncToDateTime = $toDateTime; | |
$this->syncDateTime = new \DateTimeImmutable('now', new \DateTimeZone('UTC')); | |
$this->lastObjectSyncDates = []; | |
} | |
public function getSyncFromDateTime(string $integration, string $object): \DateTimeInterface | |
{ | |
if ($this->syncFromDateTime) { | |
// The command requested a specific start date so use it | |
return $this->syncFromDateTime; | |
} | |
$key = $integration.$object; | |
if (isset($this->lastObjectSyncDates[$key])) { | |
// Use the same sync date for integrations to paginate properly | |
return $this->lastObjectSyncDates[$key]; | |
} | |
if (MauticSyncDataExchange::NAME !== $integration && $lastSync = $this->getLastSyncDateForObject($integration, $object)) { | |
// Use the latest sync date recorded | |
$this->lastObjectSyncDates[$key] = $lastSync; | |
} else { | |
// Otherwise, just sync the last 24 hours | |
$this->lastObjectSyncDates[$key] = new \DateTimeImmutable('-24 hours', new \DateTimeZone('UTC')); | |
} | |
return $this->lastObjectSyncDates[$key]; | |
} | |
public function getSyncToDateTime(): ?\DateTimeInterface | |
{ | |
if ($this->syncToDateTime) { | |
return $this->syncToDateTime; | |
} | |
return $this->syncDateTime; | |
} | |
public function getSyncDateTime(): ?\DateTimeInterface | |
{ | |
return $this->syncDateTime; | |
} | |
/** | |
* @return \DateTimeImmutable|null | |
*/ | |
public function getLastSyncDateForObject(string $integration, string $object): ?\DateTimeInterface | |
{ | |
$qb = $this->connection->createQueryBuilder(); | |
$result = $qb | |
->select('max(m.last_sync_date)') | |
->from(MAUTIC_TABLE_PREFIX.'sync_object_mapping', 'm') | |
->where( | |
$qb->expr()->eq('m.integration', ':integration'), | |
$qb->expr()->eq('m.integration_object_name', ':object') | |
) | |
->setParameter('integration', $integration) | |
->setParameter('object', $object) | |
->executeQuery() | |
->fetchOne(); | |
if (!$result) { | |
return null; | |
} | |
$lastSync = new \DateTimeImmutable($result, new \DateTimeZone('UTC')); | |
// The last sync is out of the requested sync date/time range | |
if ($this->syncFromDateTime && $lastSync < $this->syncFromDateTime) { | |
return null; | |
} | |
// The last sync is out of the requested sync date/time range | |
if ($lastSync > $this->getSyncToDateTime()) { | |
return null; | |
} | |
return $lastSync; | |
} | |
public function getInternalSyncStartDateTime(): ?\DateTimeInterface | |
{ | |
return $this->internalSyncStartDateTime; | |
} | |
public function setInternalSyncStartDateTime(): void | |
{ | |
if ($this->internalSyncStartDateTime) { | |
return; | |
} | |
$this->internalSyncStartDateTime = $this->calculateInternalSyncStartDateTime(); | |
} | |
private function calculateInternalSyncStartDateTime(): \DateTimeInterface | |
{ | |
$now = new \DateTimeImmutable('now', new \DateTimeZone('UTC')); | |
// If there is no syncToDateTime value use "now" | |
if (!$this->getSyncToDateTime()) { | |
return $now; | |
} | |
// Clone it so that we don't modify the initial object | |
$syncToDateTime = clone $this->getSyncToDateTime(); | |
// We should compare in UTC timezone | |
if (method_exists($syncToDateTime, 'setTimezone')) { | |
$syncToDateTime->setTimezone(new \DateTimeZone('UTC')); | |
} | |
// If syncToDate is less than now then use syncToDate, because otherwise we may delete | |
// changes that aren't supposed to be deleted from the sync_object_field_change_report table | |
return min($now, $syncToDateTime); | |
} | |
} | |