Recently, I needed to be able to automatically assign a different role to a user when a certain role expired. I thought I'd share the patch I made to accomplish this in case anyone else was looking for something similar.

Comments

dchaffin’s picture

Oops ... found an error with the above patch ...

role_expire.module, line 590

$role_day_period is now an array; therefore, the line needs to change from:

role_expire_write_record($uid, $role_id, mktime(0, 0, 0, date("m"), date("d") + $role_day_period, date("Y")));

... to:

role_expire_write_record($uid, $role_id, mktime(0, 0, 0, date("m"), date("d") + $role_day_period['duration'], date("Y")));

carrierawks’s picture

How would you do this with D6 though?

stewsnooze’s picture

Have you tried doing it with Rules?

phrankle’s picture

I get this error when implementing the patch and after making the $role_day_period change:

PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'new_role' in 'field list': SELECT duration, new_role FROM {role_expire_length} WHERE rid = :rid; Array ( [:rid] => 16 ) in role_expire_get_default_duration() (line 115 of /blah/public_html/blah/sites/all/modules/role_expire/role_expire.module).

phrankle’s picture

I've got a few issues with this, so I must be doing something wrong. Whenever I try to apply the patch it fails:

[user@web role_expire]$ patch < role-expire-module-new-role.patch
(Stripping trailing CRs from patch.)
patching file role_expire.module
Reversed (or previously applied) patch detected! Assume -R? [n] y
Hunk #2 FAILED at 125.
Hunk #4 FAILED at 255.
Hunk #5 FAILED at 296.
Hunk #6 succeeded at 421 (offset -11 lines).
3 out of 7 hunks FAILED -- saving rejects to file role_expire.module.rej

[user@web role_expire]$ patch < role-expire-install-new-role.patch
(Stripping trailing CRs from patch.)
patching file role_expire.install
Hunk #1 FAILED at 51.
1 out of 1 hunk FAILED -- saving rejects to file role_expire.install.rej

I can make all of the changes manually (copying and pasting from the patch to the files) except for this (from the patch):

@@ -255,7 +247,6 @@
     '#options' => _role_expire_get_role(),
     '#empty_option' => t('---select---'),
     '#empty_value' => 0,
-    '#default_value' => $defaults['new_role'],
   );

That bit of code doesn't exist starting at line 247 in the original role_expire.module for beta1. In fact, it's not in the file at all. These are lines 230-250:

 * Implements hook_form_FORM-ID_alter().
 */
function role_expire_form_user_admin_role_alter(&$form, $form_state) {
  $form['role_expire'] = array(
    '#title' => t("Default duration for the role %role",
      array('%role' => drupal_ucfirst($form['name']['#default_value']))),
    '#type' => 'textfield',
    '#size' => 8,
    '#default_value' => role_expire_get_default_duration($form['rid']['#value']),
    '#maxlength' => 5,
    '#attributes' => array('class' => array('role-expire-role-expiry')),
    '#description' => t("Default number of days this role should be active. Leave blank for no limit.")
  );
  // Reposition the submit button and delete.
  $form['submit']['#weight'] = 2;
  if (arg(4)) {
    $form['delete']['#weight'] = 3;
  }
  $form['#validate'][] = 'role_expire_user_admin_role_validate';
  $form['#submit'][] = 'role_expire_user_admin_role_submit';
}

Any idea how I can get this patch working? It looks like it might be incomplete as it doesn't actually add a form where you can select the new role as you have in your screenshot.

kaduwall’s picture

This patch would've been VERY NICE. It didn't work for me but I got a solution and wanted to share it with you.

I needed to give a new role to the user when any of the other roles expired.
Besides the anonymous and authenticated user, I have these 3 roles on my website:

- Basic User
- Premium User
- Premium Plus User

Whenever "Premium" or "Premium Plus" expired, I wanted to remove this role and give him the "Basic User" role.
After some hours of banging my head against the wall I managed to get it working.

On line 423 of the "role_expire.module" we have this:

      // If the account *does* exist, update it.
      if (!empty($account)) {
        $edit = $account->roles;
        unset($edit[$expire->rid]);
        // In the documentation for the role_expire implementation of hook_user we
        // state to use $category = 'account'.  We don't do that here because
        // that would cause the delete to occur twice.
        user_save($account, array('roles' => $edit), NULL);


Then after the "user_save" line I added this:

	$ridd = array_search('basic user', user_roles());
	$new_role[$ridd] = 'basic user';
	$edit = $account->roles + $new_role;
	user_save($account, array('roles' => $edit), NULL);


And that's it, it's working! You'll just have to change the 'basic user' to the name of the role you want.
THIS CODE IS PROBABLY UGLY and there are 2 "user_save"'s. This happens because I AM NO PHP or DRUPAL GURU, I just managed to get it working!

So, please, if you can make this code better, I'm all ears (or fingers for that matter, heh).
FULL CODE of this part:

     // If the account *does* exist, update it.
      if (!empty($account)) {
        $edit = $account->roles;
        unset($edit[$expire->rid]);
        // In the documentation for the role_expire implementation of hook_user we
        // state to use $category = 'account'.  We don't do that here because
        // that would cause the delete to occur twice.
        user_save($account, array('roles' => $edit), NULL);
	$ridd = array_search('basic user', user_roles());
	$new_role[$ridd] = 'basic user';
	$edit = $account->roles + $new_role;
	user_save($account, array('roles' => $edit), NULL);


I hope this helps!

rcodina’s picture

Version: 7.x-1.0-beta1 » 7.x-1.x-dev
Issue summary: View changes
Status: Patch (to be ported) » Needs review
StatusFileSize
new4.81 KB

I attach a patch with a new approach. It creates a new module configuration page where you can globally define which new roles should be assign given expired ones.

rcodina’s picture

If while applying the patch on #7, the hunk on file role_expire.info fails, just add this line to it:

configure = admin/config/people/role_expire

This is the URL of the new administration options for this module.

rcodina’s picture

StatusFileSize
new4.86 KB
new274 bytes

I upload a new patch which solves a bug of patch on #7. I enclose an interdiff with that patch.

rcodina’s picture

StatusFileSize
new41.4 KB

I add an screenshot of the new configuration form.

stewsnooze’s picture

@rcodina I've added you as a maintainer

rcodina’s picture

@stewsnooze Ok, thanks!

  • rcodina committed 1bff6c5 on 7.x-1.x
    Issue #1587720 by rcodina, dchaffin, kaduwall: Set new role on role...
rcodina’s picture

Status: Needs review » Fixed

  • rcodina committed 0434949 on 7.x-1.x
    Issue #1587720 by rcodina, dchaffin, kaduwall: Set new role on role...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.