configuration = $configuration; $this->flexiBeeApi = $flexiBeeApi; $this->flexiBeeUtil = $flexiBeeUtil; $this->logger = $logger; } public static function getType(): string { return static::$type; } public function sync(): void { $this->process( $this->getLastSyncTime() ); $this->updateLastSyncTime(); } public function syncSingleItem(int $id, ?int $flexiId = null): void { throw new FlexiBeeException(sprintf('Single item synchronization is not supported for type "%s"', static::getType())); } protected function process(?int $lastSyncTime = null): void { foreach ($this->getItems($lastSyncTime) as $item) { $this->logItem((array) $item); $this->processItem($item); } } abstract protected function processItem(array $item): void; protected function getItems(?int $lastSyncTime = null): iterable { if (!static::$evidenceClass) { throw new FlexiBeeException( sprintf('Class "%s" should overwrite "%s" method', get_class($this), __FUNCTION__) ); } // Pokud je nastavena evidence class, tak pro nacteni zmen pouziju ChangesAPI $changesMaxVersion = $this->getLastVersion(); // ukladam si startTime, abych mohl limitovat maximalni dobu, kterou muze sync v ramci jednoho sync cyklu bezet $startTime = microtime(true); do { // nactu si zmeny od posledni synchronizace $changes = $this->flexiBeeApi->getChanges($changesMaxVersion, static::$evidenceClass); // ulozim si maximalni verzi $changesMaxVersion = (int) max($changesMaxVersion, !empty($changes) ? (max(array_map(fn ($x) => $x['@in-version'], $changes)) + 1) : 0); // nactu si data podle ID zmen $changesIds = array_unique(array_map(fn ($x) => $x['id'], $changes)); if (!empty($changesIds)) { // zavolam preprocess kvuli pripadnym modifikacim dat $changedItems = $this->preprocessChangedItems( $this->flexiBeeApi->getEvidenceDataByIds(static::$evidenceClass, $changesIds, filters: $this->getItemsFilter()) ); // zacnu vracet polozky, aby se v synchronizaci zpracovali foreach ($changedItems as $item) { yield $item; } } // aktualizuju si posledni sesynchronizovanou verzi $this->updateLastVersion($changesMaxVersion); $isTimedOut = (microtime(true) - $startTime) > 300; // pokud sync bezi uz dele jak 5 minut, tak ji ukoncim // pravdepodobne ve Flexi vzniklo hodne zmen, tak to postupne syncneme nez blokovat sync na dlouhou dobu if ($this->mode === self::MODE_NORMAL && $isTimedOut) { break; } } while (!empty($changes)); } protected function preprocessChangedItems(array $items): array { return $items; } protected function logItem(array $item): void { if (!$this->logging) { return; } $this->logger->data( sprintf('[FlexiBee] Processing change of \'%s\'', static::getType()), [ 'Data' => $item, 'Type' => static::getType(), ] ); } protected function logUpdate(array $item): void { if (!$this->logging) { return; } $this->logger->data( sprintf('[FlexiBee] Sending to Flexi change of \'%s\'', static::getType()), [ 'Data' => $item, 'Type' => static::getType(), ] ); } protected function getLastVersion(?string $type = null): int { if ($this->mode === self::MODE_FULL) { return 0; } $dbcfg = \Settings::getDefault(); $flexiBee = $dbcfg->loadValue('flexibee') ?: []; return !empty($flexiBee['sync_versions'][$type ?: static::getType()]) ? (int) $flexiBee['sync_versions'][$type ?: static::getType()] : 0; } protected function updateLastVersion(int $version): void { if ($this->mode === self::MODE_FULL) { return; } $dbcfg = \Settings::getDefault(); $flexiBee = $dbcfg->loadValue('flexibee') ?: []; $flexiBee['sync_versions'][static::getType()] = $version; $dbcfg->saveValue('flexibee', $flexiBee); } protected function getLastSyncTime(?string $type = null): ?int { if ($this->mode === self::MODE_FULL) { return null; } $dbcfg = \Settings::getDefault(); $flexiBee = $dbcfg->loadValue('flexibee') ?: []; $this->tmpLastSync = time() - (60 * 5); return $flexiBee['timestamps'][$type ?: static::getType()] ?? null; } protected function updateLastSyncTime(): void { if ($this->mode === self::MODE_FULL) { return; } $dbcfg = \Settings::getDefault(); $flexiBee = $dbcfg->loadValue('flexibee') ?: []; $flexiBee['timestamps'][static::getType()] = $this->tmpLastSync ?: (time() - (60 * 5)); $dbcfg->saveValue('flexibee', $flexiBee); } protected function createDateTime(?int $timestamp): ?\DateTime { if (!$timestamp) { return null; } $datetime = new \DateTime(); $datetime->setTimestamp($timestamp); return $datetime; } public function setMode(int $mode): self { $this->mode = $mode; return $this; } protected function getItemsFilter(): array { return []; } }