You are here

redhen_contact.module in RedHen CRM 8

Same filename and directory in other branches
  1. 7 modules/redhen_contact/redhen_contact.module

File

modules/redhen_contact/redhen_contact.module
View source
<?php

/**
 * @file
 * Contains redhen_contact.module..
 */
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\redhen_contact\Entity\Contact;
use Drupal\redhen_contact\Entity\ContactType;

/**
 * Denotes that the contact is not active.
 */
const REDHEN_CONTACT_INACTIVE = 0;

/**
 * Denotes that the node is active.
 */
const REDHEN_CONTACT_ACTIVE = 1;

/**
 * Implements hook_help().
 */
function redhen_contact_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {

    // Main module help for the redhen_contact module.
    case 'help.page.redhen_contact':
      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('Defines the base contact entity and features.') . '</p>';
      return $output;
    default:
  }
}

/**
 * Implements hook_theme().
 */
function redhen_contact_theme() {
  $theme = [];
  $theme['redhen_contact'] = [
    'render element' => 'elements',
    'file' => 'redhen_contact.page.inc',
    'template' => 'redhen_contact',
  ];
  $theme['redhen_contact_content_add_list'] = [
    'render element' => 'content',
    'variables' => [
      'content' => NULL,
    ],
    'file' => 'redhen_contact.page.inc',
  ];
  return $theme;
}

/**
 * Implements hook_theme_suggestions_HOOK().
 */
function redhen_contact_theme_suggestions_redhen_contact(array $variables) {
  $suggestions = [];
  $contact = $variables['elements']['#redhen_contact'];
  $sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_');
  $suggestions[] = 'redhen_contact__' . $sanitized_view_mode;
  $suggestions[] = 'redhen_contact__' . $contact
    ->getType();
  $suggestions[] = 'redhen_contact__' . $contact
    ->getType() . '__' . $sanitized_view_mode;
  $suggestions[] = 'redhen_contact__' . $contact
    ->id();
  $suggestions[] = 'redhen_contact__' . $contact
    ->id() . '__' . $sanitized_view_mode;
  return $suggestions;
}

/**
 * Implements hook_views_data_alter().
 *
 * Adds a relationship from the user table to its contact entity.
 */
function redhen_contact_views_data_alter(&$data) {
  $data['users_field_data']['redhen_contact']['relationship'] = [
    'title' => t('Redhen Contact'),
    'label' => t('Redhen Contact'),
    'group' => 'User',
    'help' => t('Reference to the related Redhen Contact for a User.'),
    'id' => 'standard',
    'base' => 'redhen_contact',
    'base field' => 'uid',
    'field' => 'uid',
  ];
}

/**
 * Implements hook_tokens().
 */
function redhen_contact_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
  $replacements = [];
  if ($type == 'entity' && isset($data['entity_type']) && $data['entity_type'] == 'redhen_contact') {
    foreach ($tokens as $name => $original) {
      switch ($name) {
        case 'id':
          $replacements[$original] = $data['entity']
            ->id();
          break;
        case 'name':
          $replacements[$original] = $data['entity']
            ->getFullName();
          break;
        case 'type':
          $replacements[$original] = $data['entity']
            ->getType();
          break;
        case 'status':
          $replacements[$original] = $data['entity']
            ->isActive();
          break;
        case 'created':
          $replacements[$original] = $data['entity']
            ->getCreatedTime();
          break;
      }
    }
  }
  return $replacements;
}

/**
 * Implements hook_token_info().
 */
function redhen_contact_token_info() {
  $type = [
    'name' => t('Contact'),
    'description' => t('Tokens related to an individual Contacts.'),
    'needs-data' => 'redhen_contact',
  ];
  $redhen_contact['id'] = [
    'name' => t('Contact ID'),
    'description' => t('The unique ID of the Contact.'),
  ];
  $redhen_contact['name'] = [
    'name' => t('Contact Name'),
    'description' => t('The name of the Contact.'),
  ];
  $redhen_contact['type'] = [
    'name' => t('Contact Type'),
    'description' => t('The type (bundle) of the Contact.'),
  ];
  $redhen_contact['status'] = [
    'name' => t('Contact Status'),
    'description' => t('The status of the Contact.'),
  ];
  $redhen_contact['created'] = [
    'name' => t('Contact Created'),
    'description' => t('The timestamp the Contact was created.'),
  ];
  return [
    'types' => [
      'redhen_contact' => $type,
    ],
    'tokens' => [
      'redhen_contact' => $redhen_contact,
    ],
  ];
}

/**
 * Return an associative array of contact types to be used as an options list.
 *
 * @return array
 *   Keyed by name with a label value.
 */
function redhen_contact_type_options_list() {
  $options = [];
  foreach (ContactType::loadMultiple() as $type) {
    $options[$type
      ->id()] = $type
      ->label();
  }
  return $options;
}

/**
 * Implements hook_form_FORM_ID_alter() on the user_register_form.
 */
function redhen_contact_form_user_register_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // Get Redhen Contact settings.
  $config = \Drupal::config('redhen_contact.settings');

  // Check whether we should create a Contact on User registration.
  if ($config
    ->get('connect_users')) {

    // Get menu item to check for overridden Contact Type parameter, but only
    // when a user is registering from user/register.
    $url_exploded = array_slice(explode('/', \Drupal::request()
      ->getRequestUri()), 1);
    if ($url_exploded[0] == 'user' && $url_exploded[1] == 'register' && isset($url_exploded[2])) {
      $contact_type = $url_exploded[2];
    }
    else {

      // If a parameter was not passed, use the default contact type.
      $contact_type = $config
        ->get('registration_type');
    }

    // If a valid contact type was found, embed fields from the Contact Type on
    // the user registration form.
    $types = redhen_contact_type_options_list();
    if (array_key_exists($contact_type, $types)) {
      $contact_object = Contact::create([
        'type' => $contact_type,
      ]);
      _redhen_contact_user_embed_contact_form($form, $form_state, $contact_object, $config
        ->get('registration_form'));

      // Add a validation handler for validating the Contact form data.
      $form['#validate'][] = 'redhen_contact_user_registration_validate';

      // Add a submit handler for handling the Contact form data.
      $form['actions']['submit']['#submit'][] = 'redhen_contact_user_registration_submit';

      // Hide the Contact email field, we will use the user mail field.
      $form['redhen_contact_' . $contact_type]['email']['#access'] = FALSE;
    }
    else {
      \Drupal::messenger()
        ->addMessage(t('Invalid RedHen contact type parameter.'));
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Targets user_form.
 * Note that this also triggers on hook_form_BASE_FORM_ID_alter() for the
 * user_register_form, which has "user_form" as its base_form_id. This is why we
 * double-check the $form_id.
 */
function redhen_contact_form_user_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // Double-check the $form_id, as user_form is also a base_form_id for forms.
  if ($form_id != "user_form") {
    return;
  }

  // Load Contact using Drupal User.
  $user = $form_state
    ->getFormObject()
    ->getEntity();
  $contact = Contact::loadByUser($user);

  // If we find a Contact linked to the current User, alter the form in
  // accordance with our RedHen Contact admin settings.
  if ($contact) {

    // Get Redhen Contact settings.
    $config = \Drupal::config('redhen_contact.settings');

    // If we're mirroring the Contact's email address - disable the field.
    if ($config
      ->get('connect_users')) {
      $form['account']['mail']['#disabled'] = TRUE;
      $form['account']['mail']['#description'] .= ' ' . t('The email address for this account is managed by RedHen.');
    }

    // Embed Contact form on User edit form.
    if ($config
      ->get('embed_on_user_form')) {

      // If the User email field is disabled, hide it since the Contact email
      // field syncs to the User email field and is displayed on the embedded
      // contact form.
      // Having a disabled email field and an enabled one is confusing.
      if ($form['account']['mail']['#disabled']) {
        $form['account']['mail']['#access'] = FALSE;
      }
      _redhen_contact_user_embed_contact_form($form, $form_state, $contact, $config
        ->get('contact_user_form'));

      // If the user isn't allowed to edit any Contact of the current type, do
      // not allow them to edit this Contact's status because if they change it
      // from TRUE to FALSE they won't be able to see this Contact any more.
      //
      // Common use case is when a user has permission to edit their own
      // Contact, but not any Contact.
      $contact_types = ContactType::loadMultiple();
      foreach (array_keys($contact_types) as $contact_type) {
        if (isset($form['redhen_contact_' . $contact_type])) {
          $edit_access = AccessResult::allowedIfHasPermissions($user, [
            'edit contact entities',
            'edit any ' . $contact_type . ' contact',
          ], 'OR');
          if (!$edit_access
            ->isAllowed()) {
            $form['redhen_contact_' . $contact_type]['status']['#access'] = FALSE;
          }
        }
      }

      // Add a submit handler for handling the Contact form data.
      $form['actions']['submit']['#submit'][] = 'redhen_contact_user_update_submit';
    }
  }
}

/**
 * Helper function to embed a contact form on a user form.
 *
 * Usage note: make sure to add a submit handler, otherwise this form data will
 * just be ignored.
 *
 * @param array $form
 *   Form array.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   Form state array.
 * @param \Drupal\redhen_contact\Entity\Contact $contact
 *   The Contact to build the form on.
 */
function _redhen_contact_user_embed_contact_form(&$form, &$form_state, Contact $contact, $form_mode = 'default') {

  // Place new Contact object in form_state - we use this if an existing Contact
  // is not found to link the user being created to.
  $form_state
    ->set('redhen_contact', $contact);

  // Create form element to hold Contact fields.
  $form['redhen_contact_' . $contact
    ->getType()] = [
    '#type' => 'details',
    '#title' => str_replace('!type', ContactType::load($contact
      ->getType())
      ->label(), '!type Contact information'),
    '#tree' => TRUE,
    '#parents' => [
      'form_display_' . $contact
        ->getType(),
    ],
    '#open' => TRUE,
    '#element_validate' => [
      'redhen_contact_user_update_validate',
    ],
    // We would prefer to base this on weight of $form['account']['#weight'],
    // but that value gets changed before the form renders to be "1".
    '#weight' => 10,
  ];

  // Add EntityFormDisplay object used to build an entity's form.
  if (!$form_mode) {
    $form_mode = 'default';
  }
  $form_state
    ->set('form_display_' . $contact
    ->getType(), EntityFormDisplay::collectRenderDisplay($contact, $form_mode));

  // Build the entity's form into the placeholder form element created above.
  $form_state
    ->get('form_display_' . $contact
    ->getType())
    ->buildForm($contact, $form['redhen_contact_' . $contact
    ->getType()], $form_state);

  // Hide user linkage field when embedded.
  $form['redhen_contact_' . $contact
    ->getType()]['uid']['#access'] = FALSE;
}

/**
 * User registration form RedHen Contact validation handler.
 */
function redhen_contact_user_registration_validate($form, &$form_state) {

  // Load existing Contact by email address if one exists.
  $existing_contacts = Contact::loadByMail($form_state
    ->getValue('mail'));

  // If no pre-existing Contact, use Contact created and put into the
  // form_state array when the user_registration form was loaded.
  $contact = $existing_contacts ? current($existing_contacts) : $form_state
    ->get('redhen_contact');

  // Check whether we should update info of an existing Contact using info
  // provided on user_registration form.
  $update_existing = \Drupal::config('redhen_contact.settings')
    ->get('registration_update');

  // We have an existing contact, but it's of a different type.
  if ($existing_contacts && $contact
    ->getType() !== $form_state
    ->get('redhen_contact')
    ->getType()) {
    $form_state
      ->setError($form['account']['mail'], str_replace([
      '!type',
      '!email',
    ], [
      $contact
        ->getType(),
      $form_state
        ->getValue('mail'),
    ], 'A Contact of type "!type" is already associated with the email address "!email".'));
  }

  // We don't want to update contacts, but found an existing match.
  if ($existing_contacts && !$update_existing) {
    $form_state
      ->setError($form['account']['mail'], 'A contact already exists with that email address.');
  }

  // Existing contact is already linked to a user.
  if ($existing_contacts && !is_null($contact
    ->getUser()) && $update_existing) {
    $form_state
      ->setError($form['account']['mail'], 'A contact with that email address is already linked to a Drupal user.');
  }

  // Validate submitted field values and update Contact stored in form_state
  // to be our chosen Contact (i.e. pre-existing Contact with matching email
  // address or new Contact) with its field values updated from the values
  // supplied in the form.
  _redhen_contact_user_submission_validate($form, $form_state, $contact);
}

/**
 * User registration form RedHen Contact submit handler.
 *
 * Links a Contact to a Drupal user on user registration.
 * Contact will a pre-existing Contact if Redhen Contact admin setting to link
 * user to existing Contact is TRUE and we were able to find a Contact with an
 * email that matches the user being created. If either of these conditions is
 * false, the Contact will be created new.
 *
 * @param array $form
 *   Form array.
 * @param array $form_state
 *   Form state array.
 */
function redhen_contact_user_registration_submit($form, &$form_state) {

  // Load Contact
  $contact = $form_state
    ->get('redhen_contact');

  // Connect Drupal user to Redhen Contact.
  // We know this should happen on submit without checking anything because
  // we only embed redhen_contact fields on the user_registration form if
  // redhen_contact.settings.connect_users is TRUE.
  // See redhen_contact_form_user_register_form_alter().
  $contact
    ->setUserId($form_state
    ->getFormObject()
    ->getEntity()
    ->id());

  // Set Contact's email address to that of the new User.
  $contact
    ->setEmail($form_state
    ->getValue('mail'));

  // Save Contact associated with the user being created.
  $contact
    ->save();

  // Add message that new User was linked to a Contact.
  $message = t('User has been linked to the contact %name.', [
    '%name' => $contact
      ->label(),
  ]);

  // Update form_state Contact for later processing.
  $form_state
    ->set('redhen_contact', $contact);

  // Only display this message to CRM admins to avoid confusion.
  $user = Drupal::currentUser();
  if ($user
    ->hasPermission('administer contact entities')) {
    \Drupal::messenger()
      ->addMessage($message);
  }
}

/**
 * User edit form RedHen Contact validation handler.
 *
 * @param array $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 */
function redhen_contact_user_update_validate($form, &$form_state) {

  // Load Contact
  $contact = $form_state
    ->get('redhen_contact');

  // Validate submitted field values and update Contact stored in form_state
  // with field values from the submitted form.
  _redhen_contact_user_submission_validate($form, $form_state, $contact);
}

/**
 * User update form RedHen Contact submit handler.
 *
 * Updates a connected Contact on User update.
 *
 * @param array $form
 *   Form array.
 * @param array $form_state
 *   Form state array.
 */
function redhen_contact_user_update_submit($form, &$form_state) {

  // Load Contact
  $contact = $form_state
    ->get('redhen_contact');

  // Save changes to Contact associated with User being updated.
  $contact
    ->save();
}

/**
 * Helper function for validating Contact Form values submitted via User forms.
 *
 * @param array $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 * @param \Drupal\redhen_contact\Entity\Contact $contact
 */
function _redhen_contact_user_submission_validate($form, &$form_state, Contact $contact) {

  // Get submitted field values.

  /** @var $form_display \Drupal\core\Entity\Entity\EntityFormDisplay */
  $form_display = $form_state
    ->get('form_display_' . $contact
    ->getType());

  // Update Contact entity with values submitted on the form.
  // Do NOT overwrite fields with values with empty field values if the
  // submitted form is user_register_form. Do overwrite fields with values with
  // empty field values if the submitted form is the user_edit form.
  // This allows the user registration form to remain simple (i.e. not all
  // Contact fields shown) without clobbering existing field data for a Contact
  // while allowing the User edit form to function as expected (i.e. you can
  // delete field values).
  $form_id = $form_state
    ->getBuildInfo()['form_id'];
  if ($form_id == 'user_register_form') {
    $contact = _redhen_contact_user_submission_apply($form, $form_state, $form_display, $contact, TRUE);
  }
  elseif ($form_id == 'user_form') {
    $contact = _redhen_contact_user_submission_apply($form, $form_state, $form_display, $contact);
  }

  // Entity was validated in entityFormValidate(). This will prevent validation
  // exception from being thrown.
  $form_state
    ->getFormObject()
    ->getEntity()
    ->validate();

  // Update Contact stored in form_state to be our chosen Contact (i.e.
  // pre-existing Contact with matching email address or new Contact) with its
  // field values updated from the values supplied in the form.
  $form_state
    ->set('redhen_contact', $contact);
}

/**
 * Helper function for handling Contact Form values submitted via User forms.
 *
 * This happens when a RedHen Contact form is embedded in a User form via a form
 * alter hook, then the from is submitted. Note that this function updates the
 * $contact, but does not save the changes.
 *
 * @param array $form
 *   Form array.
 * @param array $form_state
 *   Form state array.
 * @param EntityFormDisplay $form_display
 *   EntityFormDisplay to extract field values from.
 * @param \Drupal\redhen_contact\Entity\Contact $contact
 *   RedhenContact to update.
 * @param bool $limit_values
 *   Whether to limit updated values to non-null fields.
 *
 * @return string
 *   Status message.
 */
function _redhen_contact_user_submission_apply($form, $form_state, $form_display, Contact $contact, $limit_values = FALSE) {

  // Limit field values updated on the Contact to only the fields with non-empty
  // values from the submitted form. Use this option if you don't want to
  // clobber pre-existing field values with empty field values from the form.
  if ($limit_values) {
    $value_state = redhen_contact_user_registration_form_state($form, $form_state, $contact
      ->getType());
  }
  else {
    $value_state = $form_state;
  }

  // We always update fields if the User and Contact are already linked. So, if
  // the submission came from the user_form, we apply the submitted field
  // values.
  // We only update fields on user registration if settings permit or the
  // Contact is new. To determine this, we check whether the submission came
  // from the user_register_form and if it did, we check the setting that
  // determines whether we update fields on User registration.
  $form_id = $form_state
    ->getBuildInfo()['form_id'];
  $registration_update = \Drupal::config('redhen_contact.settings')
    ->get('registration_update');
  if ($form_id == 'user_form' || $registration_update && $form_id == 'user_register_form' || $contact
    ->isNew()) {
    $values = $value_state
      ->getValues()['form_display_' . $contact
      ->getType()];
    foreach ($values as $field => $value) {
      if ($contact
        ->hasField($field)) {
        $widget = $form_display
          ->getRenderer($field);
        if ($widget) {

          // Let the widget massage the submitted values.
          $value = $widget
            ->massageFormValues($value, $form, $form_state);
        }
        $contact
          ->set($field, $value);
      }
    }
  }
  return $contact;
}

/**
 * Return form_state that includes the values from the visible form elements.
 *
 * @param array $form
 *   The RedHen contact form.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   The RedHen contact form state.
 * @param string $contact_type
 *   The RedHen Contact Type.
 *
 * @return \Drupal\Core\Form\FormStateInterface
 *   The modified form_state.
 */
function redhen_contact_user_registration_form_state(array $form, FormStateInterface $form_state, $contact_type) {

  // Start with form_state as passed.
  $limited_state = clone $form_state;

  // Reset values element since we'll be rebuilding it below.
  $field_parent_name = 'form_display_' . $form_state
    ->get('redhen_contact')
    ->getType();
  $limited_state
    ->setValues([
    $field_parent_name => [],
  ]);

  // Get Redhen Contact field definitions to determine default values.
  $contact_fields = \Drupal::service('entity_field.manager')
    ->getFieldDefinitions('redhen_contact', $contact_type);

  // Get all Redhen contact field values.
  $field_values = $form_state
    ->getValue($field_parent_name);
  $limited_field_values = [];

  // Loop through all Redhen contact field values.
  foreach ($field_values as $key => $value) {

    // Skip un-accessible children.
    if (isset($form[$key]['#access']) && !$form[$key]['#access']) {
      continue;
    }

    // Skip any empty fields.
    if (!isset($contact_fields[$key]) || !redhen_contact_form_field_has_value($contact_fields[$key], $value)) {
      continue;
    }

    // Add fields with new values to limited field values.
    $limited_field_values[$key] = $value;
  }

  // Rebuild form state with limited field values.
  $limited_state
    ->setValue($field_parent_name, $limited_field_values);
  return $limited_state;
}

/**
 * Determines if a form field has been submitted with a value.
 *
 * @param object $definition
 *   The field definition as returned by
 *   \Drupal::service('entity_field.manager')->getFieldDefinitions()
 * @param array $value
 *   The field value in the submitted form state.
 *
 * @return boolean
 *   TRUE if the field contains a value, FALSE otherwise.
 */
function redhen_contact_form_field_has_value($definition, $value) {
  if ($definition instanceof \Drupal\Core\Field\BaseFieldDefinition) {

    // Base fields can have their values compared against the field's
    // default value. If the value matches the default, the field is empty.
    if ($value === $definition
      ->getDefaultValueLiteral()) {
      return FALSE;
    }
  }
  else {
    if ($definition instanceof \Drupal\field\Entity\FieldConfig) {

      // Some entity fields require special logic to determine if they are empty.
      // Start with the field type.
      $field_type = $definition
        ->getType();
      switch ($field_type) {

        // Test an image field.
        case 'image':
          if (empty($value[0]['fids'])) {
            return FALSE;
          }
          break;
        default:

          // Default to testing the field storage definition's first column for
          // an empty value. This works for most fields.
          // e.g. An entity_reference field would have a "target_id" column,
          // which is an array key that can be tested for emptiness in the
          // field value.
          $columns = $definition
            ->getFieldStorageDefinition()
            ->getColumns();
          reset($columns);
          $column_name = key($columns);

          // Some field types store their values in $value[0].
          // Example: string, entity_reference, and telephone type fields.
          if (isset($value[0])) {
            if (array_key_exists($column_name, $value[0]) && empty($value[0][$column_name])) {
              return FALSE;
            }
          }
          else {
            if (array_key_exists($column_name, $value) && empty($value[$column_name])) {
              return FALSE;
            }
          }
          break;
      }
    }
  }
  return TRUE;
}

/**
 * Implements hook_user_format_name_alter().
 *
 * @param $name
 * @param $account
 */
function redhen_contact_user_format_name_alter(&$name, $account) {

  // If RedHen is configured to alter the username of users linked with Contacts.
  if (\Drupal::config('redhen_contact.settings')
    ->get('alter_username') == TRUE) {
    $contact = Contact::loadByUser($account);
    if ($contact) {
      $name = $contact
        ->label();
    }
  }
}

Functions

Namesort descending Description
redhen_contact_form_field_has_value Determines if a form field has been submitted with a value.
redhen_contact_form_user_form_alter Implements hook_form_FORM_ID_alter().
redhen_contact_form_user_register_form_alter Implements hook_form_FORM_ID_alter() on the user_register_form.
redhen_contact_help Implements hook_help().
redhen_contact_theme Implements hook_theme().
redhen_contact_theme_suggestions_redhen_contact Implements hook_theme_suggestions_HOOK().
redhen_contact_tokens Implements hook_tokens().
redhen_contact_token_info Implements hook_token_info().
redhen_contact_type_options_list Return an associative array of contact types to be used as an options list.
redhen_contact_user_format_name_alter Implements hook_user_format_name_alter().
redhen_contact_user_registration_form_state Return form_state that includes the values from the visible form elements.
redhen_contact_user_registration_submit User registration form RedHen Contact submit handler.
redhen_contact_user_registration_validate User registration form RedHen Contact validation handler.
redhen_contact_user_update_submit User update form RedHen Contact submit handler.
redhen_contact_user_update_validate User edit form RedHen Contact validation handler.
redhen_contact_views_data_alter Implements hook_views_data_alter().
_redhen_contact_user_embed_contact_form Helper function to embed a contact form on a user form.
_redhen_contact_user_submission_apply Helper function for handling Contact Form values submitted via User forms.
_redhen_contact_user_submission_validate Helper function for validating Contact Form values submitted via User forms.

Constants

Namesort descending Description
REDHEN_CONTACT_ACTIVE Denotes that the node is active.
REDHEN_CONTACT_INACTIVE Denotes that the contact is not active.