-
-
Notifications
You must be signed in to change notification settings - Fork 167
Expand file tree
/
Copy pathcivicrm_member_roles.module
More file actions
687 lines (625 loc) · 24.7 KB
/
civicrm_member_roles.module
File metadata and controls
687 lines (625 loc) · 24.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
<?php
// $Id: civicrm_member_roles.module,v 1.3.2.4.2.5 2008/09/01 04:17:11 posco Exp $
/**
* Copyright (C) 2010 Neil Goodman
* @license GNU General Public License version 2 or later
*
* @file
* Synchronize CiviCRM Contacts with Membership Status to a specified Drupal Role both automatically and manually.
*/
/**
* Implements hook_menu().
*/
function civicrm_member_roles_menu() {
if (!civicrm_initialize()) {
return;
}
$items = array();
$items['admin/config/civicrm/civicrm_member_roles'] = array(
'title' => 'CiviMember Roles Sync',
'description' => 'Add/remove association rules and configure settings. Also perform manual synchronization.',
'page callback' => 'civicrm_member_roles_show_rules',
'access callback' => 'user_access',
'access arguments' => array('access civicrm member role setting'),
'type' => MENU_NORMAL_ITEM,
);
$items['admin/config/civicrm/civicrm_member_roles/show_rules'] = array(
'title' => 'List Association Rule(s)',
'access callback' => 'user_access',
'access arguments' => array('access civicrm member role setting'),
'weight' => -5,
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/config/civicrm/civicrm_member_roles/add_rule'] = array(
'title' => 'Add Association Rule',
'page callback' => 'drupal_get_form',
'page arguments' => array('civicrm_member_roles_add_rule_form'),
'access callback' => 'user_access',
'access arguments' => array('access civicrm member role setting'),
'type' => MENU_LOCAL_TASK,
);
$items['admin/config/civicrm/civicrm_member_roles/add_rule/%rule_id'] = array(
'title' => 'Add Association Rule',
'page callback' => 'drupal_get_form',
'page arguments' => array('civicrm_member_roles_add_rule_form', 1),
'access callback' => 'user_access',
'access arguments' => array('access civicrm member role setting'),
'type' => MENU_LOCAL_TASK,
);
$items['admin/config/civicrm/civicrm_member_roles/configure'] = array(
'title' => 'Configure',
'page callback' => 'drupal_get_form',
'page arguments' => array('civicrm_member_roles_configure'),
'access callback' => 'user_access',
'access arguments' => array('access civicrm member role setting'),
'type' => MENU_LOCAL_TASK,
);
$items['admin/config/civicrm/civicrm_member_roles/manual_sync'] = array(
'title' => 'Manually Synchronize',
'page callback' => 'drupal_get_form',
'page arguments' => array('civicrm_member_roles_manual_sync'),
'access callback' => 'user_access',
'access arguments' => array('access civicrm member role setting'),
'type' => MENU_LOCAL_TASK,
);
return $items;
}
/**
* Implements hook_permission().
*/
function civicrm_member_roles_permission() {
return array(
'access civicrm member role setting' => array(
'title' => t('Access CiviCRM member role setting'),
'description' => t('Access Civicrm member roles synchronization.'),
),
);
}
/**
* Implements hook_user_login().
*/
function civicrm_member_roles_user_login(&$edit, $account) {
civicrm_member_roles_sync_user($account);
}
/**
* Implements hook_user_logout().
*/
function civicrm_member_roles_user_logout($account) {
civicrm_member_roles_sync_user($account);
}
function civicrm_member_roles_sync_user($account) {
if (!civicrm_initialize()) {
return;
}
if (in_array('login', variable_get('civicrm_member_roles_sync_method', array('login')), TRUE)) {
_civicrm_member_roles_sync($account->uid);
}
}
/**
* Implements hook_cron().
*/
function civicrm_member_roles_cron() {
if (!civicrm_initialize(TRUE)) {
return;
}
if (in_array('cron', variable_get('civicrm_member_roles_sync_method', array('login')), TRUE)) {
_civicrm_member_roles_sync(NULL, NULL, 'cron');
}
}
/**
* Show stored association rules and delete rules.
*/
function civicrm_member_roles_show_rules($action = NULL, $id = NULL) {
if (!civicrm_initialize()) {
return;
}
//Delete rule
if ($action == 'delete') {
if (is_numeric($id)) {
$delete = db_delete('civicrm_member_roles_rules')->condition('rule_id', $id)->execute();
if ($delete) {
drupal_set_message(t('Rule ID !1 was successfully deleted.', array('!1' => $id)));
}
else {
drupal_set_message(t('There was an error deleting the association rule. Please check your database settings and try again. If you continue to get this error message then try to reinstall CiviMember Roles Sync.'), $type = 'error');
}
}
}
$status = _civicrm_member_roles_get_data('status');
$type = _civicrm_member_roles_get_data('types');
$roles = user_roles(TRUE);
//Begin building main output table.
$header = array(
'rid' => t('Rule ID'),
'rule_name' => t('Rule Name ("CiviMember Membership Type" --> "Drupal Role")'),
'current_code' => t('Add When Status Is'),
'expired_code' => t('Remove When Status Is'),
'options' => t('Operation'),
);
$data = array();
$rules = db_select('civicrm_member_roles_rules', 'cmr')->fields('cmr')->orderBy('rule_id', 'ASC')->execute()->fetchAll();
foreach ($rules as $result) {
$codes = unserialize($result->status_codes);
$current = "";
$expired = "";
foreach ($codes['current'] as $value) {
$current .= $status[$value] . ", ";
}
foreach ($codes['expired'] as $value) {
$expired .= $status[$value] . ", ";
}
$data[] = array(
'rid' => check_plain($result->rule_id),
'rule_name' => check_plain($type[$result->type_id] . " --> " . $roles[$result->rid]),
'current_code' => check_plain(trim($current, ", ")),
'expired_code' => check_plain(trim($expired, ", ")),
'options' => l(t('edit'), 'admin/config/civicrm/civicrm_member_roles/add_rule' . '/' . check_plain($result->rule_id)) . ' ' . l(t('delete'), 'admin/config/civicrm/civicrm_member_roles/delete' . '/' . check_plain($result->rule_id)),
);
}
if (!empty($data)) {
$output['data'] = array(
'#prefix' => t("Use the 'Add Association Rule' form to add new rules.") . '<br/><br/>',
'#theme' => 'table',
'#header' => $header,
'#rows' => $data,
);
}
else {
$output = t("There are no rules currently set. Use the 'Add Association Rule' form to add one.");
}
return $output;
}
/**
* Manual sync form. Provides a sumbit button to manually sync memberships to roles.
*
* @ingroup forms
* @see civicrm_member_roles_manual_sync_submit()
*/
function civicrm_member_roles_manual_sync() {
$form = array();
$form['manual_sync'] = array(
'#type' => 'fieldset',
'#title' => t('Manual Synchronization:'),
);
$form['manual_sync']['manual_sync_submit'] = array(
'#type' => 'submit',
'#value' => t('Synchronize CiviMember Membership Types to Drupal Roles now'),
);
return $form;
}
/**
* Implements hook_submit().
*
* For the manual sync form.
*/
function civicrm_member_roles_manual_sync_submit($form, &$form_state) {
if (!civicrm_initialize()) {
return;
}
if (_civicrm_member_roles_sync()) {
drupal_set_message(t('CiviMember Memberships and Drupal Roles have been synchronized using available rules. Note: if no association rules exist then synchronization has not been completed.'));
}
else {
drupal_set_message(t('There was an error. CiviMember Memberships and Drupal Roles could not be synchronized.'), $type = 'error');
}
}
/**
* Configuration form. Allows user to edit the Automatic Synchronization Method.
*
* @ingroup forms
*/
function civicrm_member_roles_configure() {
$form = array();
$form['settings'] = array(
'#type' => 'fieldset',
'#title' => t('Settings'),
);
$form['settings']['civicrm_member_roles_sync_method'] = array(
'#type' => 'checkboxes',
'#title' => t('Automatic Synchronization Method'),
'#description' => t('Select which method CiviMember Roles Sync will use to automatically synchronize Memberships and Roles. If you choose user login/logout, you will have to run an initial "Manual Synchronization" after you create a new rule for it to be applied to all users and contacts. If you do not select an option, automatic synchronization will be disabled. You will have to use the "Manually Synchronize" form to synchronize memberships and roles yourself. Leave the default setting if you are unsure which method to use.'),
'#default_value' => variable_get('civicrm_member_roles_sync_method', array('login')),
'#options' => array(
'login' => t('Synchronize whenever a user logs in or logs out. This action is performed only on the user logging in or out.'),
'cron' => t('Synchronize when Drupal cron is ran. This action will be performed on all users and contacts.'),
'update' => t('Synchronize when membership is updated.'),
),
);
$form['settings']['civicrm_member_roles_cron_limit'] = array(
'#type' => 'textfield',
'#title' => t('Memberships Synchronized on Cron'),
'#description' => t('Enter how many Memberships and Roles you would like to synchronize per cron run. Synchronization will be performed randomly. This prevents the operation from timing out when too many items are processed at once. If this is empty, all Memberships and Roles will be processed.'),
'#default_value' => variable_get('civicrm_member_roles_cron_limit', 150),
'#element_validate' => array('element_validate_integer_positive'),
'#size' => 15,
'#maxlength' => 4,
);
return system_settings_form($form);
}
/**
* Implements hook_form().
*
* Add/edit association rules.
*
* @ingroup forms
* @see civicrm_member_roles_add_rule_validate()
* @see civicrm_member_roles_add_rule_submit()
*/
function civicrm_member_roles_add_rule_form($form = NULL, $form_state = NULL, $id = NULL) {
if (!civicrm_initialize()) {
return;
}
$membership_options = _civicrm_member_roles_get_data('types');
$status_options = _civicrm_member_roles_get_data('status');
$roles = user_roles(TRUE);
//Let's get rid of the authenticated role as it is a useless option for this module
unset($roles[2]);
//Begin add form
$form = array();
$form['add_rule'] = array(
'#type' => 'fieldset',
'#title' => t('Association Rule'),
'#description' => t('Choose a CiviMember Membership Type and a Drupal Role below. This will associate that Membership with the Role. If you would like the have the same Membership be associated with more than one role, you will need to add a second association rule after you have completed this one.'),
'#tree' => TRUE,
'#parents' => array('add_rule'),
);
$form['add_rule']['select_membership'] = array(
'#type' => 'select',
'#title' => t('Select a CiviMember Membership Type'),
'#options' => $membership_options,
'#required' => TRUE,
);
$form['add_rule']['select_role'] = array(
'#type' => 'select',
'#title' => t('Select a Drupal Role'),
'#options' => $roles,
'#required' => TRUE,
);
$form['status_code'] = array(
'#type' => 'fieldset',
'#title' => t('CiviMember Status Rules'),
'#description' => t('Select which CiviMember Statuses will be used to add or remove from the Drupal Role. An "Add" status rule will add the above role to a user account. A "Removal" status rule will remove the above role from a user account.'),
'#tree' => TRUE,
);
$form['status_code']['current'] = array(
'#type' => 'checkboxes',
'#title' => t('Add Statuses'),
'#description' => t("Select all CiviMember Status Rule(s) that represent an 'add' status."),
'#options' => $status_options,
'#required' => TRUE,
);
$form['status_code']['expired'] = array(
'#type' => 'checkboxes',
'#title' => t('Removal Statuses'),
'#description' => t("Select all CiviMember Status Rule(s) that represent a 'removal' status."),
'#options' => $status_options,
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Add association rule'),
);
//Begin edit form
if (!empty($id) && is_numeric($id)) {
$default_values = db_select('civicrm_member_roles_rules', 'cmr')->fields('cmr')->condition('rule_id', $id)->execute()->fetchObject();
if (!$default_values) {
drupal_set_message(t('There was an error in obtaining the association rule for edit. Please check your database settings and try again. If you continue to get this error message then try to reinstall CiviMember Roles Sync.'));
return $form;
}
$codes = unserialize($default_values->status_codes);
foreach ($codes['current'] as $key => $value) {
$codes['current'][$key] = check_plain($value);
}
foreach ($codes['expired'] as $key => $value) {
$codes['expired'][$key] = check_plain($value);
}
//Alter above add form with default values.
$form['add_rule']['select_membership']['#default_value'] = $default_values->type_id;
$form['add_rule']['select_role']['#default_value'] = $default_values->rid;
$form['status_code']['current']['#default_value'] = $codes['current'];
$form['status_code']['expired']['#default_value'] = $codes['expired'];
$form['edit_flag'] = array('#type' => 'hidden', '#value' => check_plain($id));
$form['submit']['#value'] = t('Edit association rule');
}
return $form;
}
/**
* Implements hook_validate().
*
* For the add/edit rule form.
*/
function civicrm_member_roles_add_rule_form_validate($form, &$form_state) {
//Make sure there is a CiviMember Membership Type and a Drupal Role selected.
if (is_numeric($form_state['values']['add_rule']['select_membership']) && is_numeric($form_state['values']['add_rule']['select_role'])) {
if ($form_state['values']['add_rule']['select_membership'] == 0 || $form_state['values']['add_rule']['select_role'] == 0) {
form_set_error('add_rule', t('You must select both a CiviMember Membership Type and a Drupal Role from the "Association Rule" section.'));
}
}
else {
form_set_error('add_rule', t('CiviMember Membership Type and Drupal Role values were not numeric.'));
}
//Check for conflicting status rules.
foreach ($form_state['values']['status_code']['current'] as $current_key => $current_value) {
if (is_numeric($form_state['values']['status_code']['expired'][$current_key]) && is_numeric($current_value)) {
if ($form_state['values']['status_code']['expired'][$current_key] > 0 && $current_value > 0) {
form_set_error('', t('You can not have the same Status Rule registered as both "Current" and "Expired".'));
}
}
else {
form_set_error('', t('Status Rules values were not numeric.'));
}
}
//Validate edit flag if set
if (isset($form_state['values']['edit_flag']) && !is_numeric($form_state['values']['edit_flag'])) {
form_set_error('', t('Edit flag was not numeric.'));
}
//Validate duplicate rules
if (!isset($form_state['values']['edit_flag'])) {
$result = FALSE;
$membershipTypeId = (int) $form_state['values']['add_rule']['select_membership'];
$roleId = (int) $form_state['values']['add_rule']['select_role'];
$sql = db_select('civicrm_member_roles_rules', 'cmr')->fields('cmr')->condition('rid', $roleId)->condition('type_id', $membershipTypeId)->execute()->fetchAll();
foreach ($sql as $values) {
if ($values) {
$result = TRUE;
break;
}
}
if ($result) {
form_set_error('', t('This rule set is already exist in data base.'));
}
}
}
/**
* Implements hook_submit().
*
* For the add/edit rule form.
*/
function civicrm_member_roles_add_rule_form_submit($form, &$form_state) {
if (!civicrm_initialize()) {
return;
}
//Build array of status rules in order to serialize into the database
$codes = array('current', 'expired');
$codes['current'] = array();
$codes['expired'] = array();
foreach ($form_state['values']['status_code']['current'] as $key => $value) {
if ($form_state['values']['status_code']['expired'][$key] > 0) {
$codes['expired'][] = $form_state['values']['status_code']['expired'][$key];
}
elseif ($value > 0) {
$codes['current'][] = $value;
}
}
//If edit_flag is set then process as an edit form, if not then process as an add form.
if (isset($form_state['values']['edit_flag'])) {
$edit_rule = db_update('civicrm_member_roles_rules')->fields(array(
'rid' => (int) $form_state['values']['add_rule']['select_role'],
'type_id' => (int) $form_state['values']['add_rule']['select_membership'],
'status_codes' => serialize($codes),
))->condition('rule_id', (int) $form_state['values']['edit_flag'])->execute();
if ($edit_rule) {
drupal_set_message(t('Your association rule has been edited.'));
}
}
else {
$add_rule = db_insert('civicrm_member_roles_rules')->fields(array(
'rid' => (int) $form_state['values']['add_rule']['select_role'],
'type_id' => (int) $form_state['values']['add_rule']['select_membership'],
'status_codes' => serialize($codes),
))->execute();
if ($add_rule) {
drupal_set_message(t('Your association rule has been added.'));
}
else {
drupal_set_message(t('There was an error adding the association rule. Please check your database settings and try again. If you continue to get this error message then try to reinstall CiviMember Roles Sync.'), $type = 'error');
}
}
}
/**
* Finds members and applies roles based on the rules defined in the settings page. If the ext_uid param is defined then
* this function will only sync one user.
*
* @param string $sync_type
* Whether we are syncing on cron, login, etc. Only cron is handled at this time.
*
* @return bool
*/
function _civicrm_member_roles_sync($ext_uid = NULL, $cid = NULL, $sync_type = NULL) {
if (!civicrm_initialize()) {
return FALSE;
}
$rules = db_query('SELECT * FROM {civicrm_member_roles_rules}')->fetchAll();
if (empty($rules) || $rules === FALSE) {
return FALSE;
}
$memberroles = $rid = array();
foreach ($rules as $ruleValues) {
$memberroles[$ruleValues->type_id][] = array(
'rid' => $ruleValues->rid,
'codes' => unserialize($ruleValues->status_codes),
);
$rid[] = $ruleValues->rid;
}
//Find all contacts that have membership rules (or just use $ext_uid)
if (empty($ext_uid) && empty($cid)) {
// Get the number of contacts to sync at once, if we're syncing on cron.
$cron_limit = variable_get('civicrm_member_roles_cron_limit', 150);
if ($sync_type == 'cron' && is_numeric($cron_limit) && $cron_limit > 0) {
$sql = "SELECT DISTINCT uf.contact_id FROM civicrm_uf_match uf
LEFT JOIN civicrm_membership m ON uf.contact_id = m.contact_id
WHERE m.id IS NOT NULL AND m.membership_type_id IN (" . implode(',', array_keys($memberroles)) . ")
ORDER BY RAND() LIMIT " . $cron_limit;
}
else {
$sql = "SELECT DISTINCT uf.contact_id, m.end_date FROM civicrm_uf_match uf
LEFT JOIN civicrm_membership m ON uf.contact_id = m.contact_id
WHERE m.id IS NOT NULL AND m.membership_type_id IN (" . implode(',', array_keys($memberroles)) . ")
ORDER BY m.end_date DESC";
//let's prioritise those ending last as then we are more likely to get relevant ones if it doesn't complete
//obviously a better fix would be for it to chunk & save where it is up to
}
$params = CRM_Core_DAO::$_nullArray;
$errorMsg = 'unknown error';
$errorParams = array();
}
else {
if (!empty($ext_uid)) {
//Let's get the UID's Contact ID so we only grab one record from the CiviCRM DB.
$uid = $ext_uid;
$sql = "SELECT contact_id FROM civicrm_uf_match WHERE uf_id = %1";
$params = array(1 => array($uid, "Integer"));
$errorMsg = 'The uid: @uid did not have a CiviCRM Contact ID.';
$errorParams = array('@uid' => (int) $ext_uid);
}
else {
// Seems silly to add this query, but the while loop below needs result set.
$sql = "SELECT id AS contact_id FROM civicrm_contact WHERE id = %1";
$params = array(1 => array($cid, "Integer"));
$errorMsg = 'Unable to get CiviCRM Contact ID @cid.';
$errorParams = array('@uid' => (int) $cid);
}
}
$contacts = CRM_Core_DAO::executeQuery($sql, $params);
if ($contacts->N == 0) {
watchdog('civicrm_member_roles',
$errorMsg,
$errorParams,
WATCHDOG_ERROR
);
return FALSE;
}
$allRoles = user_roles(TRUE);
while ($contacts->fetch()) {
$cid = $contacts->contact_id;
$uid = CRM_Core_BAO_UFMatch::getUFId($cid);
if (empty($uid)) {
continue;
}
//Get all memberships of contact
$memParams = array(
'contact_id' => $cid,
'options' => array('limit' => 0),
);
//CRM-16000 added try/catch to api call
try {
$memberships = civicrm_api3('membership', 'get', $memParams);
}
catch (CiviCRM_API3_Exception $e) {
$error = $e->getMessage();
return $error;
}
//CRM-16000 remove inactive memberships if member has both active and inactive memberships
if ($memberships['count'] > 1) {
$params = array(
'sequential' => 1,
'name' => array('IN' => array("Deceased", "Cancelled", "Pending", "Expired")),
);
try {
$result = civicrm_api3('MembershipStatus', 'get', $params);
}
catch (CiviCRM_API3_Exception $e) {
$error = $e->getMessage();
return $error;
}
foreach ($result['values'] as $value) {
$inactive[] = $value['id'];
}
foreach ($memberships['values'] as $key => $membership) {
//Do not unset if inactive membership status is chosen as an option for synchronization.
$inactiveStatusSync = FALSE;
if (!empty($memberroles[$membership['membership_type_id']])) {
foreach ($memberroles[$membership['membership_type_id']] as $rolerule) {
if (in_array($membership['status_id'], $rolerule['codes']['current'])) {
$inactiveStatusSync = TRUE;
}
}
}
if (in_array($membership['status_id'], $inactive) && !$inactiveStatusSync) {
unset($memberships['values'][$key]);
}
}
}
$contactMemberships = CRM_Utils_Array::value('values', $memberships);
$addRoles = array();
$expRoles = array();
foreach ($contactMemberships as $membership) {
if (is_array($memberroles[$membership['membership_type_id']])) {
foreach ($memberroles[$membership['membership_type_id']] as $rolerule) {
if (in_array($membership['status_id'], $rolerule['codes']['current'])) {
$addRoles[] = $rolerule['rid'];
}
elseif (in_array($membership['status_id'], $rolerule['codes']['expired'])) {
$expRoles[] = $rolerule['rid'];
}
}
}
if (count($addRoles) > 0 || count($expRoles) > 0) {
$addRoles = array_unique($addRoles);
$expRoles = array_unique($expRoles);
$account = user_load($uid, TRUE);
if ($account !== FALSE) {
// Remove expired roles
$userNeedsUpdate = FALSE;
if (!empty($expRoles)) {
foreach ($expRoles as $expiredRole) {
if (isset($account->roles[$expiredRole])) {
unset($account->roles[$expiredRole]);
$userNeedsUpdate = TRUE;
}
}
}
// Add new roles
foreach ($addRoles as $addRole) {
if (!user_has_role($addRole, $account)) {
$account->roles[$addRole] = $allRoles[$addRole];
$userNeedsUpdate = TRUE;
}
}
if ($userNeedsUpdate) {
// Overwrite the user's roles to the ones we've set
user_save($account, ['roles' => $account->roles]);
}
}
}
}
}
return TRUE;
}
/**
* This function returns an array of either membership types or status rules depending on the $type param.
*/
function _civicrm_member_roles_get_data($type) {
if (!civicrm_initialize()) {
return;
}
switch ($type) {
case 'status':
$sql = 'SELECT id, name FROM civicrm_membership_status;';
break;
case 'types':
$sql = 'SELECT id, name FROM civicrm_membership_type;';
break;
default:
$sql = '';
drupal_set_message(t('Invalid parameter was given to _civicrm_member_roles_get_data(). Param: "!1".', array('!1' => $type)));
break;
}
$dao = CRM_Core_DAO::executeQuery($sql);
$result = array();
while ($dao->fetch()) {
$result[$dao->id] = $dao->name;
}
unset($dao);
if (empty($result)) {
drupal_set_message(t('CiviMember Membership Types or Status Rules have not been configured. Please do so on the "Administer CiviCRM" page.'), $type = 'error');
}
return $result;
}
function civicrm_member_roles_civicrm_post($op, $objname, $objid, &$objref) {
if ($objname == "Membership") {
if (in_array('update', variable_get('civicrm_member_roles_sync_method', array('login')), TRUE)) {
_civicrm_member_roles_sync(NULL, $objref->contact_id);
}
}
}