You are here

uc_role.module in Ubercart 8.4

Grants roles upon accepted payment of products.

The uc_role module will grant specified roles upon purchase of specified products. Granted roles can be set to have a expiration date. Users can also be notified of the roles they are granted and when the roles will expire/need to be renewed/etc.

File

uc_role/uc_role.module
View source
<?php

/**
 * @file
 * Grants roles upon accepted payment of products.
 *
 * The uc_role module will grant specified roles upon purchase of specified
 * products. Granted roles can be set to have a expiration date. Users can also
 * be notified of the roles they are granted and when the roles will
 * expire/need to be renewed/etc.
 */
use Drupal\Core\Database\Query\Condition;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\user\Entity\User;
use Drupal\user\UserInterface;
use Drupal\uc_role\Event\NotifyRevokeEvent;
use Drupal\uc_role\Event\NotifyReminderEvent;

/**
 * Implements hook_help().
 */
function uc_role_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'uc_role.expiration':
      return '<p>' . t('Ubercart grants certain roles to customers when they purchase products with a role assignment feature. These can be permanent or temporary roles. Here you can view and edit when temporary roles are set to expire.') . '</p>';
    case 'uc_product.feature_add':
      if ($route_match
        ->getRawParameter('fid') == 'role') {
        return '<p>' . t('Add roles through this page and then use the <a href=":url">Rules interface</a> to limit which orders they are applied to. Most important is the order status on which role granting will be triggered.', [
          ':url' => Url::fromRoute('entity.rules_reaction_rule.collection')
            ->toString(),
        ]) . '</p>';
      }
      break;
  }
}

/**
 * Implements hook_cron().
 */
function uc_role_cron() {
  $roles_config = \Drupal::config('uc_role.settings');
  $reminder_granularity = $roles_config
    ->get('reminder_granularity');
  $reminder_qty = $roles_config
    ->get('reminder_length');
  $connection = \Drupal::database();
  $query = $connection
    ->select('uc_roles_expirations', 'e')
    ->fields('e');
  $condition = new Condition('OR');
  $condition
    ->condition('e.expiration', \Drupal::time()
    ->getRequestTime(), '<=');
  if ($reminder_granularity != 'never') {
    $and = new Condition('AND');
    $condition
      ->condition($and
      ->isNull('e.notified')
      ->condition('e.expiration', _uc_role_get_expiration($reminder_qty, $reminder_granularity, \Drupal::time()
      ->getRequestTime()), '<='));
  }
  $query
    ->condition($condition);
  $result = $query
    ->execute();
  foreach ($result as $expiration) {
    $account = User::load($expiration
      ->id());

    // Cleanup if user or role was deleted already.
    if (!$account || !in_array($expiration->rid, array_keys($account->getRoles))) {
      uc_role_delete($expiration, $expiration->rid, TRUE);
    }
    elseif ($expiration->expiration <= \Drupal::time()
      ->getRequestTime()) {

      /* rules_invoke_event('uc_role_notify_revoke', $account, $expiration); */
      $event = new NotifyRevokeEvent($account, $expiration);
      \Drupal::service('event_dispatcher')
        ->dispatch($event::EVENT_NAME, $event);
      uc_role_revoke($account, $expiration->rid);
    }
    elseif ($reminder_granularity != 'never') {

      /* rules_invoke_event('uc_role_notify_reminder', $account, $expiration); */
      $event = new NotifyReminderEvent($account, $expiration);
      \Drupal::service('event_dispatcher')
        ->dispatch($event::EVENT_NAME, $event);
      $connection
        ->update('uc_roles_expirations')
        ->fields([
        'notified' => 1,
      ])
        ->condition('uid', $account
        ->id())
        ->condition('rid', $expiration->rid)
        ->execute();
    }
  }
}

/**
 * Implements hook_theme().
 */
function uc_role_theme() {
  return [
    'uc_role_user_expiration' => [
      'render element' => 'form',
      'file' => 'uc_role.theme.inc',
      'function' => 'theme_uc_role_user_expiration',
    ],
    'uc_role_user_new' => [
      'render element' => 'form',
      'file' => 'uc_role.theme.inc',
      'function' => 'theme_uc_role_user_new',
    ],
  ];
}

/**
 * Implements hook_form_user_profile_form_alter().
 */
function uc_role_form_user_profile_form_alter(&$form, FormStateInterface $form_state) {
  if (!\Drupal::currentUser()
    ->hasPermission('administer users')) {
    return;
  }
  $roles_config = \Drupal::config('uc_role.settings');
  $account = $form_state
    ->getFormObject()
    ->getEntity();
  $role_choices = _uc_role_get_choices(array_keys($account
    ->getRoles()));
  $polarity_widget = [
    '#type' => 'select',
    '#options' => [
      'add' => '+',
      'remove' => '-',
    ],
  ];
  $quantity_widget = [
    '#type' => 'textfield',
    '#size' => 4,
    '#maxlength' => 4,
  ];
  $granularity_widget = [
    '#type' => 'select',
    '#options' => [
      'day' => t('day(s)'),
      'week' => t('week(s)'),
      'month' => t('month(s)'),
      'year' => t('year(s)'),
    ],
  ];
  $form['uc_role'] = [
    '#type' => 'details',
    '#title' => t('Ubercart roles'),
    '#weight' => 10,
    '#theme' => 'uc_role_user_new',
  ];
  $form['uc_role']['expirations'] = [
    '#type' => 'fieldset',
    '#title' => t('Pending expirations'),
    '#weight' => 0,
    '#theme' => 'uc_role_user_expiration',
  ];
  $form['uc_role']['expirations']['table']['#tree'] = TRUE;

  // Create the expirations table.
  $connection = \Drupal::database();
  $expirations = $connection
    ->query('SELECT * FROM {uc_roles_expirations} WHERE uid = :uid', [
    ':uid' => $account
      ->id(),
  ]);
  foreach ($expirations as $expiration) {
    $form['uc_role']['expirations']['table'][$expiration->rid] = [
      'name' => [
        '#type' => 'value',
        '#value' => _uc_role_get_name($expiration->rid),
      ],
      'remove' => [
        '#type' => 'checkbox',
      ],
      'expiration' => [
        '#type' => 'value',
        '#value' => $expiration->expiration,
      ],
      'polarity' => $polarity_widget,
      'qty' => $quantity_widget,
      'granularity' => $granularity_widget,
    ];
  }

  // Option to allow temporary roles.
  if (!empty($role_choices)) {
    $form['uc_role']['new_role'] = [
      '#type' => 'checkbox',
      '#title' => t('Add role'),
    ];
    $form['uc_role']['new_role_add'] = [
      '#type' => 'select',
      '#default_value' => $roles_config
        ->get('default_role'),
      '#options' => $role_choices,
    ];
    $form['uc_role']['new_role_add_for'] = [
      '#markup' => ' ' . t('for') . ' ',
    ];
    $form['uc_role']['new_role_add_qty'] = $quantity_widget;
    $form['uc_role']['new_role_add_granularity'] = $granularity_widget;
    if (($default_granularity = $roles_config
      ->get('default_granularity')) != 'never') {
      $form['uc_role']['new_role_add_qty'] = $form['uc_role']['new_role_add_qty'] + [
        '#default_value' => $roles_config
          ->get('default_length'),
      ];
      $form['uc_role']['new_role_add_granularity'] = $form['uc_role']['new_role_add_granularity'] + [
        '#default_value' => $default_granularity,
      ];
    }
  }
  $form['#validate'][] = 'uc_role_user_validate';
  return $form;
}

/**
 * User profile form validate handler.
 *
 * @see uc_role_form_user_profile_form_alter()
 */
function uc_role_user_validate($form, FormStateInterface $form_state) {
  $edit = $form_state
    ->getValues();

  // Validate the amount of time for the expiration.
  if (!empty($edit['new_role'])) {
    if (intval($edit['new_role_add_qty']) < 1) {
      $form_state
        ->setErrorByName('new_role_add_qty', t('The expiration length must be a positive integer'));
    }
  }

  // Validate adjusted expirations.
  if (isset($edit['table'])) {
    foreach ((array) $edit['table'] as $rid => $value) {

      // We don't validate if nothing was actually selected, the role, or the
      // expiration is removed.
      if ($value['qty'] == 0 || $value['remove'] == 1 || !$edit['roles'][$rid]) {
        continue;
      }
      $qty = $value['qty'];
      $qty *= $value['polarity'] == 'add' ? 1 : -1;
      $new_expiration = _uc_role_get_expiration($qty, $value['granularity'], $value['expiration']);
      if (\Drupal::time()
        ->getRequestTime() > $new_expiration) {
        $form_state
          ->setErrorByName('qty', t('The new expiration date, %date, has already occurred.', [
          '%date' => \Drupal::service('date.formatter')
            ->format($new_expiration, 'short'),
        ]));
      }
    }
  }
}

/**
 * Implements hook_user_cancel().
 */
function uc_role_user_cancel($edit, AccountInterface $account, $method) {
  uc_role_delete($account);
}

/**
 * Implements hook_user_presave().
 */
function uc_role_user_presave(UserInterface $account) {
  if (!\Drupal::currentUser()
    ->hasPermission('administer users')) {
    return;
  }

  // Grant a new role if a new temporary role is added.
  if (!empty($account->new_role)) {

    // Save our role info, but don't save the user; user.module will do that.
    uc_role_grant($account, $account->new_role, _uc_role_get_expiration($account->new_role_add_qty, $account->new_role_add_granularity), FALSE);

    // Push in values so user.module will save in the roles.
    $account->roles[$account->new_role_add] = _uc_role_get_name($account->new_role_add);

    // Reset the new role form.
    unset($account->new_role);
    unset($account->new_role_add);
    unset($account->new_role_add_qty);
    unset($account->new_role_add_qty);
  }

  // Check if any temporary role actions were taken.
  if (isset($account->table)) {
    foreach ($account->table as $rid => $value) {

      // Remove this expiration.
      if ($value['remove']) {
        uc_role_delete($account, $rid);
      }
      else {
        if ($value['qty'] && $account
          ->hasRole($rid)) {
          $qty = $value['qty'];
          $qty *= $value['polarity'] == 'add' ? 1 : -1;
          uc_role_renew($account, $rid, _uc_role_get_expiration($qty, $value['granularity'], $value['expiration']));
        }
      }
    }
  }

  // If a user's role is removed using Drupal, then so is any expiration data.
  if (isset($account->original->roles)) {
    foreach ($account->original->roles as $rid => $role) {
      if (!in_array($rid, $account
        ->getRoles()) && $rid != AccountInterface::AUTHENTICATED_ROLE) {
        uc_role_delete($account, $rid);
      }
    }
  }
}

/**
 * Implements hook_user_view().
 */
function uc_role_user_view(array &$build, UserInterface $account, EntityViewDisplayInterface $display, $view_mode) {
  $user = \Drupal::currentUser();

  // Only show if this user can access all role expirations, or if it's the same
  // user and the expirations are showing on the user pages.
  // Kick out anonymous or other view modes.
  $show_expiration = \Drupal::config('uc_role.settings')
    ->get('default_show_expiration');
  if ($view_mode == 'full' && $user
    ->isAuthenticated() && ($user
    ->id() == $account
    ->id() && $show_expiration || $user
    ->hasPermission('view all role expirations'))) {
    $connection = \Drupal::database();
    $expirations = $connection
      ->query('SELECT * FROM {uc_roles_expirations} WHERE uid = :uid', [
      ':uid' => $account
        ->id(),
    ]);
    foreach ($expirations as $expiration) {
      $build['uc_role'][$expiration->rid] = [
        '#type' => 'item',
        '#title' => _uc_role_get_name($expiration->rid),
        '#markup' => t('This role will expire on @date', [
          '@date' => \Drupal::service('date.formatter')
            ->format($expiration->expiration, 'short'),
        ]),
      ];
    }
    if (isset($build['uc_role'])) {

      // There are role expirations, so need a container.
      $build['uc_role'] += [
        '#type' => 'item',
        '#weight' => '-1',
        '#title' => t('Expiring roles'),
      ];
    }
  }
}

/**
 * Implements hook_uc_order_product_can_ship().
 */
function uc_role_uc_order_product_can_ship($product) {
  $connection = \Drupal::database();
  $roles = $connection
    ->query('SELECT * FROM {uc_roles_products} WHERE nid = :nid', [
    ':nid' => $product->nid->target_id,
  ]);
  foreach ($roles as $role) {

    // If the model is empty, keep looking. (Everyone needs a role model...)
    if (empty($role->model)) {
      continue;
    }

    // If there's an adjusted SKU, use it... otherwise use the node SKU.
    $sku = empty($product->data['model']) ? $product->model->value : $product->data['model'];

    // Keep looking if it doesn't match.
    if ($sku != $role->model) {
      continue;
    }
    return $role->shippable;
  }
}

/**
 * Implements hook_uc_product_feature().
 */
function uc_role_uc_product_feature() {
  $features[] = [
    'id' => 'role',
    'title' => t('Role assignment'),
    'callback' => 'Drupal\\uc_role\\Form\\RoleFeatureForm',
    'delete' => 'uc_role_feature_delete',
    'settings' => 'Drupal\\uc_role\\Form\\FeatureSettingsForm',
  ];
  return $features;
}

/**
 * Implements hook_uc_store_status().
 */
function uc_role_uc_store_status() {
  $message = [];
  $role_choices = _uc_role_get_choices();
  if (empty($role_choices)) {
    $message[] = [
      'status' => 'warning',
      'title' => t('Roles'),
      'desc' => t('There are no product role(s) that can be assigned upon product purchase. Set product roles in the <a href=":url">product settings</a> under the role assignment settings tab.', [
        ':url' => Url::fromRoute('uc_product.settings')
          ->toString(),
      ]),
    ];
  }
  else {
    $message[] = [
      'status' => 'ok',
      'title' => t('Roles'),
      'desc' => t('The role(s) %roles are set to be used with the Role Assignment product feature.', [
        '%roles' => implode(', ', $role_choices),
      ]),
    ];
  }
  return $message;
}

/**
 * Gets role name.
 *
 * @param int $rid
 *   The Drupal role id number.
 *
 * @return string|false
 *   A string containing the name of the role, returns FALSE if rid is invalid.
 */
function _uc_role_get_name($rid) {
  $roles = user_role_names(TRUE);
  return !is_null($roles[$rid]) ? $roles[$rid] : FALSE;
}

/**
 * Gets available roles for granting on product purchase.
 *
 * @param array $exclude
 *   A list of role ids to exclude from the list.
 *
 * @return array
 *   An assoc array with key = rid and value = role name.
 */
function _uc_role_get_choices(array $exclude = []) {
  $output = [];

  // Get roles from Drupal, excluding Anonymous and Authenticated.
  $roles = user_role_names(TRUE);
  unset($roles[AccountInterface::AUTHENTICATED_ROLE]);

  // User set specific roles that we must use?
  $selected = \Drupal::config('uc_role.settings')
    ->get('default_role_choices');

  // If there's none, or if none are checked, use all of em.
  $default = empty($selected) || array_sum($selected) == 0;
  foreach ($roles as $rid => $name) {
    if ($default || !empty($selected[$rid]) && !in_array($rid, $exclude)) {
      $output[$rid] = $roles[$rid];
    }
  }
  return $output;
}

/**
 * Deletes all role data associated with a given product feature.
 *
 * @param int $pfid
 *   An Ubercart product feature ID.
 */
function uc_role_feature_delete($pfid) {
  $connection = \Drupal::database();
  $connection
    ->delete('uc_roles_products')
    ->condition('pfid', $pfid)
    ->execute();
}

/**
 * Deletes an expiration using user id or user id and rid.
 *
 * This function deletes expirations associated with users and roles. If
 * no role ID is passed, the function deletes all role expirations associated
 * with the given user. Otherwise, the function only deletes expirations whose
 * user and role IDs match. If any roles were actually deleted, the function
 * notifies the user. The menu cache is then flushed, as privileges to view
 * menu items may have been lost in the process.
 *
 * @param \Drupal\user\UserInterface $account
 *   A Drupal user object.
 * @param string $rid
 *   A Drupal role ID.
 * @param bool $silent
 *   When set to TRUE will suppress any Drupal messages from this function.
 */
function uc_role_delete(UserInterface $account, $rid = NULL, $silent = FALSE) {
  $connection = \Drupal::database();
  $query = $connection
    ->delete('uc_roles_expirations')
    ->condition('uid', $account
    ->id());
  if ($rid) {
    $query
      ->condition('rid', $rid);
  }

  // Echo the deletion only if something was actually deleted.
  if ($query
    ->execute() && !$silent) {
    if (\Drupal::currentUser()
      ->id() == $account
      ->id()) {
      \Drupal::messenger()
        ->addMessage(t('The expiration of your %role_name role has been deleted.', [
        '%role_name' => _uc_role_get_name($rid),
      ]));
    }
    else {
      $username = [
        '#theme' => 'username',
        '#account' => $account,
      ];
      \Drupal::messenger()
        ->addMessage(t('The expiration of %role_name role for the user @user has been deleted.', [
        '@user' => drupal_render($username),
        '%role_name' => _uc_role_get_name($rid),
      ]));
    }
  }
}

/**
 * Revokes a role on a given user.
 *
 * This function deletes a given role from a user's list of roles, as
 * well as removing any expiration data associated with the user/role.
 * The function notifies the user of revocation.
 *
 * @param \Drupal\user\UserInterface $account
 *   A Drupal user object.
 * @param string $rid
 *   A Drupal role ID.
 * @param bool $silent
 *   When set to TRUE will suppress any Drupal messages from this function.
 */
function uc_role_revoke(UserInterface &$account, $rid, $silent = FALSE) {

  // Remove this role from the user's list.
  $account
    ->removeRole($rid);
  $account
    ->save();

  // Remove our record of the expiration.
  uc_role_delete($account, $rid, $silent);
  $connection = \Drupal::database();
  $role_name = $connection
    ->query('SELECT name FROM {role} WHERE rid = :rid', [
    ':rid' => $rid,
  ])
    ->fetchField();
  if (!$silent) {
    if (\Drupal::currentUser()
      ->id() == $account
      ->id()) {
      \Drupal::messenger()
        ->addMessage(t('Your %role role has been revoked.', [
        '%role' => $role_name,
      ]));
    }
    else {
      $username = [
        '#theme' => 'username',
        '#account' => $account,
      ];
      \Drupal::messenger()
        ->addMessage(t('@user has had the %role role revoked.', [
        '@user' => drupal_render($username),
        '%role' => $role_name,
      ]));
    }
  }
}

/**
 * Grants a role to a given user.
 *
 * This function grants a given role to a user's list of roles. If there
 * is a previous record of this user/role combination, it is first removed.
 * The function then saves the user (if $user_save is TRUE). Next, a check
 * to verify the role actually exists, if not, no expiration data is stored.
 * The menu cache is flushed, as new menu items may be visible after the
 * new role is granted. The function notifies the user of the role grant.
 *
 * @param \Drupal\user\UserInterface $account
 *   A Drupal user object.
 * @param string $rid
 *   A Drupal role ID.
 * @param int $timestamp
 *   When this role will expire.
 * @param bool $save_user
 *   Optimization to prevent unnecessary user saving when calling from
 *   uc_role_user_presave().
 * @param bool $silent
 *   When set to TRUE will suppress any Drupal messages from this function.
 */
function uc_role_grant(UserInterface &$account, $rid, $timestamp, $save_user = TRUE, $silent = FALSE) {

  // First, delete any previous record of this user/role association.
  uc_role_delete($account, $rid, $silent);
  if ($save_user) {

    // Punch the role into the user object.
    $account
      ->addRole($rid);
    $account
      ->save();
  }

  // If the role expires, keep a record.
  $connection = \Drupal::database();
  if (!is_null($timestamp)) {
    $connection
      ->insert('uc_roles_expirations')
      ->fields([
      'uid' => $account
        ->id(),
      'rid' => $rid,
      'expiration' => $timestamp,
    ])
      ->execute();
  }

  // Display the message if appropriate.
  if (!$silent) {
    $role_name = $connection
      ->query('SELECT name FROM {role} WHERE rid = :rid', [
      ':rid' => $rid,
    ])
      ->fetchField();
    if (\Drupal::currentUser()
      ->id() == $account
      ->id()) {
      $message = t('You have been granted the %role role.', [
        '%role' => $role_name,
      ]);
    }
    else {
      $username = [
        '#theme' => 'username',
        '#account' => $account,
      ];
      $message = t('@user has been granted the %role role.', [
        '@user' => drupal_render($username),
        '%role' => $role_name,
      ]);
    }
    if ($timestamp) {
      $message .= ' ' . t('It will expire on %date', [
        '%date' => \Drupal::service('date.formatter')
          ->format($timestamp, 'short'),
      ]);
    }
    \Drupal::messenger()
      ->addMessage($message);
  }
}

/**
 * Renews a given role on a user.
 *
 * This function updates expiration time on a role already granted to a
 * user. First the function checks the new expiration. If it never expires,
 * the function deletes the past expiration record and returns, leaving
 * management up to Drupal. Otherwise, the record is updated with the new
 * expiration time, and the user is notified of the change.
 *
 * @param \Drupal\user\UserInterface $account
 *   A Drupal user object.
 * @param string $rid
 *   A Drupal role ID.
 * @param int $timestamp
 *   When this role will expire.
 * @param bool $silent
 *   When set to TRUE will suppress any Drupal messages from this function.
 */
function uc_role_renew(UserInterface $account, $rid, $timestamp, $silent = FALSE) {

  // If it doesn't expire, we'll remove our data associated with it.
  // After that, Drupal will take care of it.
  if (is_null($timestamp)) {
    uc_role_delete($account, $rid);
    return;
  }

  // Update the expiration date and reset the notified flag.
  $connection = \Drupal::database();
  $connection
    ->update('uc_roles_expirations')
    ->fields([
    'expiration' => $timestamp,
    'notified' => NULL,
  ])
    ->condition('uid', $account
    ->id())
    ->condition('rid', $rid)
    ->execute();
  if (!$silent) {
    $role_name = $connection
      ->query('SELECT name FROM {role} WHERE rid = :rid', [
      ':rid' => $rid,
    ])
      ->fetchField();
    if (\Drupal::currentUser()
      ->id() == $account
      ->id()) {
      $message = t('Your %role role has been renewed. It will expire on %date.', [
        '%role' => $role_name,
        '%date' => \Drupal::service('date.formatter')
          ->format($timestamp, 'short'),
      ]);
    }
    else {
      $username = [
        '#theme' => 'username',
        '#account' => $account,
      ];
      $message = t("@user's %role role has been renewed. It will expire on %date.", [
        '@user' => drupal_render($username),
        '%role' => $role_name,
        '%date' => \Drupal::service('date.formatter')
          ->format($timestamp, 'short'),
      ]);
    }
    \Drupal::messenger()
      ->addMessage($message);
  }
}

/**
 * Returns an expiration time stamp given a period of time.
 *
 * @param int $duration
 *   The amount of time until expiration.
 * @param string $granularity
 *   A string representing the granularity's name (e.g. "day", "month", etc.).
 * @param int $start_time
 *   (optional) The starting date for when the role will last. Defaults to
 *   the current time.
 *
 * @return int|null
 *   A UNIX timestamp representing the second that expiration takes place,
 *   or NULL if the expiration should never occur.
 */
function _uc_role_get_expiration($duration, $granularity, $start_time = NULL) {

  // Never expires?
  if ($granularity == 'never') {
    return NULL;
  }
  $start_time = !is_null($start_time) ? $start_time : \Drupal::time()
    ->getRequestTime();
  $operator = $duration < 0 ? '' : '+';
  return strtotime($operator . $duration . ' ' . $granularity, $start_time);
}

Functions

Namesort descending Description
uc_role_cron Implements hook_cron().
uc_role_delete Deletes an expiration using user id or user id and rid.
uc_role_feature_delete Deletes all role data associated with a given product feature.
uc_role_form_user_profile_form_alter Implements hook_form_user_profile_form_alter().
uc_role_grant Grants a role to a given user.
uc_role_help Implements hook_help().
uc_role_renew Renews a given role on a user.
uc_role_revoke Revokes a role on a given user.
uc_role_theme Implements hook_theme().
uc_role_uc_order_product_can_ship Implements hook_uc_order_product_can_ship().
uc_role_uc_product_feature Implements hook_uc_product_feature().
uc_role_uc_store_status Implements hook_uc_store_status().
uc_role_user_cancel Implements hook_user_cancel().
uc_role_user_presave Implements hook_user_presave().
uc_role_user_validate User profile form validate handler.
uc_role_user_view Implements hook_user_view().
_uc_role_get_choices Gets available roles for granting on product purchase.
_uc_role_get_expiration Returns an expiration time stamp given a period of time.
_uc_role_get_name Gets role name.