|null $localChanges * @param Collection $distContacts * @param Collection $localContacts * @return Collection */ public function execute(SyncDto $sync, ?array $localChanges, Collection $distContacts, Collection $localContacts): Collection { $this->sync = $sync; $missings = $this->preparePushMissedContacts(Arr::get($localChanges, 'added', []), $distContacts, $localContacts); return app(AddressBookContactsPush::class) ->execute($sync, collect(), $localChanges) ->union($missings); } /** * Get list of requests of missed contacts. * * @param array $added * @param Collection $distContacts * @param Collection $localContacts * @return Collection */ private function preparePushMissedContacts(array $added, Collection $distContacts, Collection $localContacts): Collection { $backend = $this->backend(); $distUuids = $distContacts->map(function (ContactDto $contact) use ($backend): string { return $backend->getUuid($contact->uri); }); $addedUuids = collect($added)->map(function (string $uri) use ($backend): string { return $backend->getUuid($uri); }); return collect($localContacts) ->filter(function (Contact $contact) use ($distUuids, $addedUuids) { return ! $distUuids->contains($contact->uuid) && ! $addedUuids->contains($contact->uuid); })->map(function (Contact $contact) use ($backend): PushVCard { $card = $backend->prepareCard($contact); return new PushVCard($this->sync->subscription, new ContactPushDto( $card['uri'], $contact->distant_etag, $card['carddata'], $contact->id, ContactPushDto::MODE_MATCH_ANY ) ); }); } }