Skip to content

Commit

Permalink
Add configuration option for matching users with CiviCRM contacts on …
Browse files Browse the repository at this point in the history
…login
  • Loading branch information
jensschuppe committed Nov 19, 2024
1 parent d168069 commit c0bdb74
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 20 deletions.
16 changes: 1 addition & 15 deletions civiremote.module
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ use Drupal\civiremote;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Url;
use Drupal\user\UserInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;

/**
* Implements hook_entity_insert().
Expand All @@ -22,19 +20,7 @@ function civiremote_entity_insert(EntityInterface $entity) {
* Implements hook_user_login().
*/
function civiremote_user_login(UserInterface $account) {
// Synchronise user roles with CiviRemote roles retrieved from CiviCRM.
try {
civiremote\User::synchroniseRoles($account);
}
catch (Exception $exception) {
user_logout();
Drupal::messenger()->addError(
t('Could not complete login. Please try again later or contact the site administrator.')
);
$url = Url::fromRoute('<front>')->toString();
$response = new RedirectResponse($url);
$response->send();
}
civiremote\User::login($account);
}

/**
Expand Down
1 change: 1 addition & 0 deletions config/install/civiremote.settings.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
cmrf_connector: civiremote
acquire_civiremote_id: false
match_blocked_users: false
match_on_login: false
9 changes: 9 additions & 0 deletions config/schema/civiremote.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ civiremote.settings:
match_blocked_users:
type: boolean
label: 'Match blocked users'
match_on_login:
type: boolean
label: 'Acquire CiviRemote ID on login'
match_on_login_exclude_roles:
type: sequence
label: 'Roles to exclude when matching on login'
sequence:
type: string
label: 'Role'
match_contact_mapping:
type: sequence
label: 'Parameter mapping'
Expand Down
49 changes: 44 additions & 5 deletions src/Form/CiviRemoteConfigForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,35 @@
namespace Drupal\CiviRemote\Form;

use Drupal;
use Drupal\Component\Utility\Html;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\field\Entity\FieldConfig;
use Drupal\user\RoleInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\cmrf_core;
use Drupal\user\RoleStorageInterface;

class CiviRemoteConfigForm extends ConfigFormBase {

/* @var cmrf_core\Core $cmrf_core */
/** @var cmrf_core\Core $cmrf_core */
public $cmrf_core;

/** @var \Drupal\user\RoleStorageInterface $roleStorage */
public $roleStorage;

/**
* CiviRemoteConfigForm constructor.
*
* @param cmrf_core\Core $cmrf_core
* @param \Drupal\user\RoleStorageInterface $roleStorage
*/
public function __construct(cmrf_core\Core $cmrf_core) {
public function __construct(cmrf_core\Core $cmrf_core, RoleStorageInterface $roleStorage) {
$this->cmrf_core = $cmrf_core;
$this->roleStorage = $roleStorage;
}

/**
Expand All @@ -46,10 +54,13 @@ public static function create(ContainerInterface $container) {
/**
* Inject dependencies.
* @var cmrf_core\Core $cmrf
* @var \Drupal\user\RoleStorageInterface $roleStorage
*/
$cmrf = $container->get('cmrf_core.core');
$roleStorage = $container->get('entity_type.manager')->getStorage('user_role');
return new static(
$cmrf
$cmrf,
$roleStorage
);
}

Expand Down Expand Up @@ -84,14 +95,19 @@ public function buildForm(array $form, FormStateInterface $form_state) {
'#required' => TRUE,
];

$form['acquire_civiremote_id'] = [
$form['match_contacts'] = [
'#type' => 'fieldset',
'#title' => $this->t('CiviCRM Contact Matching'),
];

$form['match_contacts']['acquire_civiremote_id'] = [
'#type' => 'checkbox',
'#title' => $this->t('Acquire CiviRemote ID'),
'#description' => $this->t('Whether to match a new user to a CiviCRM contact and store the CiviRemote ID returned by CiviCRM.'),
'#default_value' => $config->get('acquire_civiremote_id'),
];

$form['match_blocked_users'] = [
$form['match_contacts']['match_blocked_users'] = [
'#type' => 'checkbox',
'#title' => $this->t('Match blocked users'),
'#description' => $this->t('Whether to match blocked users to a CiviCRM contact. If unchecked, only active users will be matched.'),
Expand All @@ -101,6 +117,27 @@ public function buildForm(array $form, FormStateInterface $form_state) {
],
];

$form['match_contacts']['match_on_login'] = [
'#type' => 'checkbox',
'#title' => $this->t('Acquire CiviRemote ID on login'),
'#description' => $this->t('Whether to match existing users without a CiviRemote ID when they log in.'),
'#default_value' => $config->get('match_on_login'),
'#states' => [
'visible' => [':input[name="acquire_civiremote_id"]' => ['checked' => TRUE]],
],
];

$form['match_contacts']['match_on_login_exclude_roles'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Roles to exclude when matching on login'),
'#description' => $this->t('Users with one of the selected roles will be escluded from acquiring a CiviCRM Contact ID during login.'),
'#options' => array_map(fn(RoleInterface $role) => Html::escape($role->label()), $this->roleStorage->loadMultiple()),
'#default_value' => $config->get('match_on_login_exclude_roles') ?? [],
'#states' => [
'visible' => [':input[name="match_on_login"]' => ['checked' => TRUE]],
],
];

$form['match_contact_mapping'] = [
'#type' => 'fieldset',
'#title' => $this->t('Parameter mapping'),
Expand Down Expand Up @@ -209,6 +246,8 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
$config->set('cmrf_connector', $form_state->getValue('cmrf_connector'));
$config->set('acquire_civiremote_id', $form_state->getValue('acquire_civiremote_id'));
$config->set('match_blocked_users', $form_state->getValue('match_blocked_users'));
$config->set('match_on_login', $form_state->getValue('match_on_login'));
$config->set('match_on_login_exclude_roles', $form_state->getValue('match_on_login_exclude_roles'));
$config->set('match_contact_mapping', $form_state->getValue('match_contact_mapping_table'));
$config->save();
parent::submitForm($form, $form_state);
Expand Down
33 changes: 33 additions & 0 deletions src/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,39 @@ public static function create(UserInterface $user) {
}
}

/**
* Act on user login.
*
* @param \Drupal\user\UserInterface $user
*/
public static function login(UserInterface $user) {
try {
// Acquire CiviRemote ID on login if configured.
if (!$civiremote_id = $user->get('civiremote_id')->getValue()) {
$config = Drupal::config('civiremote.settings');
if (
$config->get('acquire_civiremote_id')
&& $config->get('match_on_login')
&& [] === array_intersect($user->getRoles(), $config->get('match_on_login_exclude_roles'))
) {
self::matchContact($user);
}
}

// Synchronise user roles with CiviRemote roles retrieved from CiviCRM.
self::synchroniseRoles($user);
}
catch (\Exception $exception) {
user_logout();
Drupal::messenger()->addError(
t('Could not complete login. Please try again later or contact the site administrator.')
);
$url = Url::fromRoute('<front>')->toString();
$response = new RedirectResponse($url);
$response->send();
}
}

/**
* Match a CiviCRM contact and set the returned CiviRemote ID on the user.
*
Expand Down

0 comments on commit c0bdb74

Please sign in to comment.