Maintain local ⭤ remote in sync with automatic AT Protocol parity for Laravel (alpha & unstable)
at dev 77 lines 1.9 kB view raw
1<?php 2 3namespace SocialDept\AtpParity\Sync; 4 5use Illuminate\Database\Eloquent\Model; 6use SocialDept\AtpParity\Concerns\SyncsWithAtp; 7use SocialDept\AtpSchema\Data\Data; 8 9/** 10 * Detects conflicts between local and remote record versions. 11 */ 12class ConflictDetector 13{ 14 /** 15 * Check if there's a conflict between local model and remote record. 16 */ 17 public function hasConflict(Model $model, Data $record, string $cid): bool 18 { 19 // No conflict if model doesn't have local changes 20 if (! $this->modelHasLocalChanges($model)) { 21 return false; 22 } 23 24 // No conflict if CID matches (same version) 25 if ($this->getCid($model) === $cid) { 26 return false; 27 } 28 29 return true; 30 } 31 32 /** 33 * Check if the model has local changes since last sync. 34 */ 35 protected function modelHasLocalChanges(Model $model): bool 36 { 37 // Use trait method if available 38 if ($this->usesTrait($model, SyncsWithAtp::class)) { 39 return $model->hasLocalChanges(); 40 } 41 42 // Fallback: compare updated_at with a sync timestamp if available 43 $syncedAt = $model->getAttribute('atp_synced_at'); 44 45 if (! $syncedAt) { 46 return true; 47 } 48 49 $updatedAt = $model->getAttribute('updated_at'); 50 51 if (! $updatedAt) { 52 return false; 53 } 54 55 return $updatedAt > $syncedAt; 56 } 57 58 /** 59 * Get the CID from a model. 60 */ 61 protected function getCid(Model $model): ?string 62 { 63 $column = config('parity.columns.cid', 'atp_cid'); 64 65 return $model->getAttribute($column); 66 } 67 68 /** 69 * Check if a model uses a specific trait. 70 * 71 * @param class-string $trait 72 */ 73 protected function usesTrait(Model $model, string $trait): bool 74 { 75 return in_array($trait, class_uses_recursive($model)); 76 } 77}