diff --git a/lib/BackgroundJob/OrganizationContactSyncJob.php b/lib/BackgroundJob/OrganizationContactSyncJob.php index e22912ff..1d581cf8 100644 --- a/lib/BackgroundJob/OrganizationContactSyncJob.php +++ b/lib/BackgroundJob/OrganizationContactSyncJob.php @@ -94,6 +94,17 @@ protected function run($argument): void } $this->logger->info('[OrganizationContactSyncJob] Starting scheduled organization sync'); - $this->orgSyncService->performScheduledSync(); + try { + $this->orgSyncService->performScheduledSync(); + } catch (\Throwable $e) { + $this->logger->error( + '[OrganizationContactSyncJob] Fatal error during sync — cron pass protected', + [ + 'error' => $e->getMessage(), + 'file' => $e->getFile(), + 'line' => $e->getLine(), + ] + ); + }//end try }//end run() }//end class diff --git a/lib/Controller/ContactpersonenController.php b/lib/Controller/ContactpersonenController.php index 31f8dd17..796741bf 100644 --- a/lib/Controller/ContactpersonenController.php +++ b/lib/Controller/ContactpersonenController.php @@ -671,7 +671,7 @@ public function updateUserGroups(string $username, array $groups=[]): JSONRespon $curCatalogGroups = []; foreach ($currentGroups as $group) { - if (in_array(needle: $group->getGID() === true, haystack: $allowedGroups) === true) { + if (in_array(needle: $group->getGID(), haystack: $allowedGroups) === true) { $curCatalogGroups[] = $group->getGID(); } } diff --git a/lib/Service/OrganizationSyncService.php b/lib/Service/OrganizationSyncService.php index 7dd9b4ce..5640abb7 100644 --- a/lib/Service/OrganizationSyncService.php +++ b/lib/Service/OrganizationSyncService.php @@ -426,11 +426,9 @@ public function performContactSync(int $batchSize=100, int $maxExecutionSeconds= $contactEntityObject = $contactEntity->getObject(); $contactEntityObject['username'] = $contact['uid']; - // Temporarily remove organisatie field to avoid validation error. - // (schema expects object type but field stores a UUID string). - $savedOrganisatie = $contactEntityObject['organisatie'] ?? null; - unset($contactEntityObject['organisatie']); - + // Keep organisatie in the object so it is never temporarily absent from the + // persisted record. The schema validation warning for a UUID-string value is + // benign compared to a data-corruption window where the field is missing. $contactEntity->setObject($contactEntityObject); $objectService->saveObject( object: $contactEntity, @@ -440,15 +438,6 @@ public function performContactSync(int $batchSize=100, int $maxExecutionSeconds= _multitenancy: false ); - // Restore the organisatie field so the link is preserved. - if ($savedOrganisatie !== null) { - $restoredData = $contactEntity->getObject(); - $restoredData['organisatie'] = $savedOrganisatie; - $contactEntity->setObject($restoredData); - $objectMapper = \OC::$server->get('OCA\OpenRegister\Db\MagicMapper'); - $objectMapper->update($contactEntity); - } - $stats['contactPersonsProcessed']++; } catch (\Exception $e) { $stats['errors'][] = $contact['uuid'].': '.$e->getMessage(); @@ -493,8 +482,10 @@ public function performUserSync(): array $platform = $this->db->getDatabasePlatform(); $isPostgres = $platform instanceof \Doctrine\DBAL\Platforms\PostgreSQLPlatform; - $jsonContainsCheck = "JSON_CONTAINS(oo.users, CONCAT('\"', o.username, '\"')) = 0"; if ($isPostgres === true) { + $jsonContainsCheck = "NOT (oo.users::jsonb @> to_jsonb(o.username::text))"; + } else { + $jsonContainsCheck = "JSON_CONTAINS(oo.users, CONCAT('\"', o.username, '\"')) = 0"; } // Find contacts with a username whose username is NOT in their org's users array. @@ -503,7 +494,7 @@ public function performUserSync(): array ->from($contactTableName, 'o') ->leftJoin('o', 'openregister_organisations', 'oo', 'oo.uuid = o.organisatie') ->where($qb->createFunction('o.username IS NOT NULL')) - ->andWhere($qb->createFunction('o.username !== '.$qb->createNamedParameter(''))) + ->andWhere($qb->createFunction('o.username <> '.$qb->createNamedParameter(''))) ->andWhere($qb->createFunction('o.organisatie IS NOT NULL')) ->andWhere($qb->createFunction($jsonContainsCheck)); @@ -2815,8 +2806,10 @@ public function performOptimizedManualSync(int $maxRounds=10, int $batchSize=100 */ public function performScheduledSync(int $minutesBack=0): array { - $syncModeValue = 'incremental'; if ($minutesBack === 0) { + $syncModeValue = 'full'; + } else { + $syncModeValue = 'incremental'; } $this->logger->info(