Solution for Sessions for Google sync users
Issue 1
The proposed fix suggested on Regression: Local users gets Profile wizard on each login Ā· Issue #10637 Ā· salesagility/SuiteCRM Ā· GitHub still wonāt work, because in reloadPreferences() in the modules/UserPreferences/UserPreference.php that inner if
if ($row) {
if (!$GLOBALS['current_user']->id || $GLOBALS['current_user']->user_name === $user->user_name){
$_SESSION[$user->user_name . '_PREFERENCES'][$category] = unserialize(base64_decode($row['contents']));
}
$user->user_preferences[$category] = unserialize(base64_decode($row['contents']));
return true;
} else {
if (!$GLOBALS['current_user']->id || $GLOBALS['current_user']->user_name === $user->user_name){
$_SESSION[$user->user_name . '_PREFERENCES'][$category] = array();
}
$user->user_preferences[$category] = array();
}
will never be true for your GoogleāSync user when run under cron, since current_user is always the admin. As a result, the sync userās session bucket never gets populatedāinstead it falls through to the āelseā and gets reset to an empty array. That change was introduced in commit ea756b13f0ae606997c0ccb4382e1a72902a9207 (āAdd check for current user on session preferencesā) and has broken GoogleāSync users
Fix
Or remove the condition completely
if (!$GLOBALS['current_user']->id || $GLOBALS['current_user']->user_name === $user->user_name){
Or add an extra condition like
if (PHP_SAPI === 'cli' || $GLOBALS['current_user']->user_name === $user->user_name){
Whenever PHP is invoked from the commandāline (for example by your cron job), its āServer APIā string (PHP_SAPI) is set to cli. In contrast, when PHP runs as an Apache module it might be apache2handler, or under PHPāFPM itās fpmācgi, etc.
This will always be true in the cron context, because youāre literally calling php -f cron.php (the CLI binary), not going through the web server. That guarantees your sessionāreload logic fires under cron even though current_user is still āadmin.
Issue 2
On the other hand, the function getGoogleClient in the file include/GoogleSync/GoogleSyncBase.php needs also a small fix for code optimization so it does not refresh the Google API token every minute. To fix this, pass the āno-sessionā flag (0) as the third argument and the category as the fourth:
By changing from
$this->workingUser->setPreference('GoogleApiToken', base64_encode(json_encode($client->getAccessToken())), 'GoogleSync');
to
$this->workingUser->setPreference('GoogleApiToken', base64_encode(json_encode($client->getAccessToken())), 0,'GoogleSync');
you are making sure that the generated GoogleApiToken is actually saved under the user preference GoogleSync and not Global
If you make this change the token is saved under the GoogleSync category, so subsequent runs will load the existing token and only refresh when itās actually expired.
The current behaviour means that the function getGoogleClient always perceives the GoogleApiToken as expired and forces the token to be reloaded because it cannot find it in the GoogleSync preference.