@@ -155,6 +155,7 @@ public function getContactList(string $userId): Generator {
155
155
* @return array
156
156
*/
157
157
public function importContacts (string $ userId , ?string $ uri , int $ key , ?string $ newAddrBookName ): array {
158
+ $ existingAddressBook = null ;
158
159
if ($ key === 0 ) {
159
160
$ addressBooks = $ this ->contactsManager ->getUserAddressBooks ();
160
161
foreach ($ addressBooks as $ k => $ ab ) {
@@ -180,19 +181,48 @@ public function importContacts(string $userId, ?string $uri, int $key, ?string $
180
181
if (!$ addressBook ) {
181
182
return ['error ' => 'no such address book ' ];
182
183
}
184
+ $ existingAddressBook = $ addressBook ;
183
185
}
184
186
185
187
$ groupsById = $ this ->getContactGroupsById ($ userId );
186
188
$ contacts = $ this ->getContactList ($ userId );
187
189
$ nbAdded = 0 ;
190
+ $ nbUpdated = 0 ;
188
191
$ totalContactNumber = 0 ;
189
192
foreach ($ contacts as $ k => $ c ) {
190
193
$ totalContactNumber ++;
191
- // avoid existing contacts
192
- if ($ this ->contactExists ($ c , $ key )) {
193
- $ this ->logger ->debug ('Skipping contact which already exists ' , ['contact ' => $ c , 'app ' => Application::APP_ID ]);
194
+
195
+ $ googleResourceName = $ c ['resourceName ' ] ?? null ;
196
+ if ($ googleResourceName === null ) {
197
+ $ this ->logger ->debug ('Skipping contact with no resourceName ' , ['contact ' => $ c , 'app ' => Application::APP_ID ]);
194
198
continue ;
195
199
}
200
+ // contacts are not displayed in the Contacts app if there are slashes in their URI...
201
+ $ googleResourceName = str_replace ('/ ' , '_ ' , $ googleResourceName );
202
+
203
+ // check if contact exists and needs to be updated
204
+ $ existingContact = null ;
205
+ if ($ existingAddressBook !== null ) {
206
+ $ existingContact = $ this ->cdBackend ->getCard ($ key , $ googleResourceName );
207
+ if ($ existingContact ) {
208
+ $ googleUpdateTime = $ c ['metadata ' ]['sources ' ][0 ]['updateTime ' ] ?? null ;
209
+ if ($ googleUpdateTime === null ) {
210
+ $ googleUpdateTimestamp = 0 ;
211
+ } else {
212
+ try {
213
+ $ googleUpdateTimestamp = (new Datetime ($ googleUpdateTime ))->getTimestamp ();
214
+ } catch (Exception | Throwable $ e ) {
215
+ $ googleUpdateTimestamp = 0 ;
216
+ }
217
+ }
218
+
219
+ if ($ googleUpdateTimestamp <= $ existingContact ['lastmodified ' ]) {
220
+ $ this ->logger ->debug ('Skipping existing contact which is up-to-date ' , ['contact ' => $ c , 'app ' => Application::APP_ID ]);
221
+ continue ;
222
+ }
223
+ }
224
+ }
225
+
196
226
$ vCard = new VCard ();
197
227
198
228
$ displayName = '' ;
@@ -406,11 +436,20 @@ public function importContacts(string $userId, ?string $uri, int $key, ?string $
406
436
}
407
437
}
408
438
409
- try {
410
- $ this ->cdBackend ->createCard ($ key , 'goog ' . $ k , $ vCard ->serialize ());
411
- $ nbAdded ++;
412
- } catch (Throwable | Exception $ e ) {
413
- $ this ->logger ->warning ('Error when creating contact ' , ['exception ' => $ e , 'app ' => Application::APP_ID ]);
439
+ if ($ existingContact === null || $ existingContact === false ) {
440
+ try {
441
+ $ this ->cdBackend ->createCard ($ key , $ googleResourceName , $ vCard ->serialize ());
442
+ $ nbAdded ++;
443
+ } catch (Throwable |Exception $ e ) {
444
+ $ this ->logger ->warning ('Error when creating contact ' , ['exception ' => $ e , 'contact ' => $ c , 'app ' => Application::APP_ID ]);
445
+ }
446
+ } else {
447
+ try {
448
+ $ this ->cdBackend ->updateCard ($ key , $ googleResourceName , $ vCard ->serialize ());
449
+ $ nbUpdated ++;
450
+ } catch (Throwable |Exception $ e ) {
451
+ $ this ->logger ->warning ('Error when updating contact ' , ['exception ' => $ e , 'contact ' => $ c , 'app ' => Application::APP_ID ]);
452
+ }
414
453
}
415
454
}
416
455
$ this ->logger ->debug ($ totalContactNumber . ' contacts seen ' , ['app ' => Application::APP_ID ]);
@@ -419,34 +458,10 @@ public function importContacts(string $userId, ?string $uri, int $key, ?string $
419
458
if (isset ($ contactGeneratorReturn ['error ' ])) {
420
459
return $ contactGeneratorReturn ;
421
460
}
422
- return ['nbAdded ' => $ nbAdded ];
423
- }
424
-
425
- /**
426
- * @param array $contact
427
- * @param int $addressBookKey
428
- * @return bool
429
- */
430
- private function contactExists (array $ contact , int $ addressBookKey ): bool {
431
- $ displayName = null ;
432
- // $familyName = null;
433
- // $firstName = null;
434
- if (isset ($ contact ['names ' ]) && is_array ($ contact ['names ' ])) {
435
- foreach ($ contact ['names ' ] as $ n ) {
436
- $ displayName = $ n ['displayName ' ] ?? '' ;
437
- // $familyName = $n['familyName'] ?? '';
438
- // $firstName = $n['givenName'] ?? '';
439
- break ;
440
- }
441
- if ($ displayName ) {
442
- $ searchResult = $ this ->contactsManager ->search ($ displayName , ['FN ' ]);
443
- foreach ($ searchResult as $ resContact ) {
444
- if ($ resContact ['FN ' ] === $ displayName && (int )$ resContact ['addressbook-key ' ] === $ addressBookKey ) {
445
- return true ;
446
- }
447
- }
448
- }
449
- }
450
- return false ;
461
+ return [
462
+ 'nbSeen ' => $ totalContactNumber ,
463
+ 'nbAdded ' => $ nbAdded ,
464
+ 'nbUpdated ' => $ nbUpdated ,
465
+ ];
451
466
}
452
467
}
0 commit comments