pdo = $pdo; $this->source = $source; if (!isset($source['id']) || empty($source['id'])) { throw new \Exception('Source ID is required for sync service'); } $this->sourceId = (int) $source['id']; } public function startSync(string $syncType = 'full'): int { // Create sync log entry $this->syncLog = new SyncLog($this->pdo); $syncLogId = $this->createSyncLog($syncType, 'started'); $this->syncLog->id = $syncLogId; try { $this->executeSync($syncType); // Update sync log as completed $this->updateSyncLog($syncLogId, 'completed', [ 'processed_items' => $this->getProcessedCount(), 'new_items' => $this->getNewCount(), 'updated_items' => $this->getUpdatedCount(), 'deleted_items' => $this->getDeletedCount() ]); } catch (Exception $e) { // Update sync log as failed $this->updateSyncLog($syncLogId, 'failed', [ 'message' => $e->getMessage(), 'errors' => [$e->getMessage()] ]); throw $e; } return $syncLogId; } private function createSyncLog(string $syncType, string $status): int { $data = [ 'source_id' => $this->sourceId, 'sync_type' => $syncType, 'status' => $status, 'total_items' => 0, 'processed_items' => 0, 'new_items' => 0, 'updated_items' => 0, 'deleted_items' => 0, 'started_at' => date('Y-m-d H:i:s') ]; $columns = array_keys($data); $placeholders = array_map(fn($col) => ":$col", $columns); $sql = "INSERT INTO sync_logs (" . implode(', ', $columns) . ") VALUES (" . implode(', ', $placeholders) . ")"; $stmt = $this->pdo->prepare($sql); $stmt->execute($data); return (int) $this->pdo->lastInsertId(); } private function updateSyncLog(int $syncLogId, string $status, array $stats = []): bool { $data = [ 'status' => $status, 'processed_items' => $stats['processed_items'] ?? 0, 'new_items' => $stats['new_items'] ?? 0, 'updated_items' => $stats['updated_items'] ?? 0, 'deleted_items' => $stats['deleted_items'] ?? 0, 'completed_at' => date('Y-m-d H:i:s') ]; if (!empty($stats['errors'])) { $data['errors'] = json_encode($stats['errors']); } if (!empty($stats['message'])) { $data['message'] = $stats['message']; } $setClause = array_map(fn($col) => "$col = :$col", array_keys($data)); $sql = "UPDATE sync_logs SET " . implode(', ', $setClause) . " WHERE id = :id"; $data['id'] = $syncLogId; $stmt = $this->pdo->prepare($sql); return $stmt->execute($data); } abstract protected function executeSync(string $syncType): void; protected function getProcessedCount(): int { return 0; // Override in subclasses } protected function getNewCount(): int { return 0; // Override in subclasses } protected function getUpdatedCount(): int { return 0; // Override in subclasses } protected function getDeletedCount(): int { return 0; // Override in subclasses } protected function logProgress(string $message): void { // Update sync log with progress message if ($this->syncLog) { $this->updateSyncLog($this->syncLog->id, 'running', [ 'message' => $message ]); } } }