@@ -548,7 +548,7 @@ public static function match_user_from_contact($contact) {
548548 */
549549 public static function process_enrolment_registration (stdClass $ enrolmentinstance ,
550550 registration_persistent $ registration ,
551- contact_persistent $ contact = null ) {
551+ ? contact_persistent $ contact = null ) {
552552 // Load plugin class instance.
553553 $ plugin = api::get_enrolment_plugin ();
554554 // Get plugin config.
@@ -706,34 +706,38 @@ public static function save_resource_information_to_persistents($enrolmentinstan
706706 throw new moodle_exception ('missingresource ' ,
707707 null , null , null , 'course ' ); // Course is Event ot Online Activity.
708708 }
709- // Check for existing registration record.
710- $ registration = registration_persistent::get_record (
711- ['sourceguid ' => $ sourceguid ]
712- );
713- if (!$ registration ) {
714- // Now we try by user and enrolment instance.
715- $ contact = contact_persistent::get_record (
716- ['sourceid ' => $ contactresource ->ContactID ]
709+ // ARLO-77: one registration row per (userid, enrolid). Look up by user+course when we
710+ // already know the user, falling back to the incoming sourceguid.
711+ $ existingcontact = contact_persistent::get_record (['sourceid ' => $ contactresource ->ContactID ]);
712+ $ registration = null ;
713+ if ($ existingcontact && $ existingcontact ->get ('userid ' ) > 0 ) {
714+ $ registration = registration_persistent::get_record (
715+ ['userid ' => $ existingcontact ->get ('userid ' ), 'enrolid ' => $ enrolmentinstance ->id ]
717716 );
718- if (!empty ($ contact )) {
719- $ registration = registration_persistent::get_record (
720- ['userid ' => $ contact ->get ('userid ' ), 'enrolid ' => $ enrolmentinstance ->id ]
721- );
722- if (!empty ($ registration )) {
723- // We don't want to re-process the registrations if it hasn't been modified since the last sync.
724- $ lastsourcemodifieddb = $ registration ->get ('sourcemodified ' );
725- $ lastsourcemodifiedapi = $ resource ->LastModifiedDateTime ;
726- // It must be newer, if has the same timestamp we already processed it.
727- if ($ lastsourcemodifieddb > $ lastsourcemodifiedapi ) {
728- return [$ registration , $ contactresource , true ];
729- }
717+ }
718+ $ registration = $ registration ?: registration_persistent::get_record (['sourceguid ' => $ sourceguid ]);
719+
720+ if ($ registration ) {
721+ // Nothing newer to apply - short-circuit so the outcomes-push -> memberships-poll
722+ // loop doesn't re-run the enrolment pipeline every cycle.
723+ if ($ registration ->get ('sourcemodified ' ) >= $ resource ->LastModifiedDateTime ) {
724+ return [$ registration , $ existingcontact , true ];
725+ }
726+ // Pair switched to a new Arlo registration ID. Drop any orphan row already holding
727+ // the incoming sourceguid (UNIQUE index) before updating in place.
728+ if ($ registration ->get ('sourceguid ' ) !== $ sourceguid ) {
729+ $ orphan = registration_persistent::get_record (['sourceguid ' => $ sourceguid ]);
730+ if ($ orphan && $ orphan ->get ('id ' ) != $ registration ->get ('id ' )) {
731+ $ orphan ->delete ();
730732 }
733+ $ registration ->set ('sourceguid ' , $ sourceguid );
734+ $ registration ->set ('sourceid ' , $ sourceid );
731735 }
732-
736+ } else {
733737 $ registration = new registration_persistent ();
734738 $ registration ->set ('sourceid ' , $ sourceid );
735739 $ registration ->set ('sourceguid ' , $ sourceguid );
736- }
740+ }
737741 $ registration ->set ('enrolid ' , $ enrolmentinstance ->id );
738742 $ registration ->set ('attendance ' , $ resource ->Attendance );
739743 $ registration ->set ('outcome ' , $ resource ->Outcome );
@@ -754,8 +758,8 @@ public static function save_resource_information_to_persistents($enrolmentinstan
754758 $ registration ->set ('sourceonlineactivityid ' , $ onlineactivityresource ->OnlineActivityID );
755759 $ registration ->set ('sourceonlineactivityguid ' , $ onlineactivityresource ->UniqueIdentifier );
756760 }
757- // Check for existing contact record.
758- $ contact = $ registration ->get_contact ();
761+ // Check for existing contact record. Reuse the lookup we did above when available.
762+ $ contact = $ existingcontact ?: $ registration ->get_contact ();
759763 // Create new contact.
760764 if (!$ contact ) {
761765 $ contact = new contact_persistent ();
@@ -785,8 +789,7 @@ public static function save_resource_information_to_persistents($enrolmentinstan
785789 $ registration ->set ('errormessage ' , '' );
786790 $ registration ->set ('enrolmentfailure ' , 0 );
787791 $ registration ->save ();
788- // Return registration and contact persistents.
789- return array ($ registration , $ contact );
792+ return [$ registration , $ contact , false ];
790793 }
791794
792795}
0 commit comments