Synchronising WordPress Users and CiviCRM Contacts
Whilst trying to clean up some logic in the CiviCRM-WordPress plugin I have come across a mismatch in how the CiviCRM-Drupal module and the CiviCRM-WordPress plugin synchronises the CMS User to the corresponding CiviCRM Contact. See this Mattermost thread for preliminary discussion.
There are currently two different types of call to CRM_Core_BAO_UFMatch::synchronize()
happening:
- In
CiviCRM_For_WordPress::initialize()
(set up the session) - In
CiviCRM_For_WordPress::invoke()
andCiviCRM_For_WordPress_Users::sync_user()
(do a full User->Contact sync)
This is the reason for the behaviour that @totten identified and that I don't think should happen at that point, i.e.:
If you access a
civicrm/*
page, then it autocreates a Contact.
As per the Mattermost discussion, it seems to me that the types of call should be:
- In
CiviCRM_For_WordPress::initialize()
andCiviCRM_For_WordPress::invoke()
(set up the session) - In
CiviCRM_For_WordPress_Users::sync_user()
(do a full User->Contact sync)
This pattern reverts the types of calls to their pre-4.6 state. My fault for the change back then
My proposal is to keep the calls to CRM_Core_BAO_UFMatch::synchronize()
in both CiviCRM_For_WordPress::initialize()
and CiviCRM_For_WordPress::invoke()
but to make the calls indirectly via a new method in the CiviCRM_For_WordPress_Users
class. The reason for this is that:
- It is possible that some code calls
civi_wp()->initialize()
,civicrm_wp_initialize()
orcivicrm_initialize()
before the WordPress User has been properly set up. I've seen this in the wild, though I can't remember where. When this happens, I don't thinkCRM_Core_BAO_UFMatch::synchronize()
should be called. TheCiviCRM_For_WordPress_Users
class can keep track of the state of the WordPress User and make sure the call occurs only at the appropriate time. - If no calls have succeeded by the time
CiviCRM_For_WordPress::invoke()
runs, thenCRM_Core_BAO_UFMatch::synchronize()
will be called correctly when it's most definitely needed. TheCiviCRM_For_WordPress_Users
class will know if it's been called already.
I don't think this change will have any adverse effects (in fact it should have marginally beneficial effects by only calling CRM_Core_BAO_UFMatch::synchronize()
when needed) but if anyone knows of code that expects Contacts to be created a civicrm/*
page then shout here.