You are here

party_user.module in Party 7

Same filename and directory in other branches
  1. 8.2 modules/party_user/party_user.module

Support for linking users to parties

File

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

/**
 * @file
 * Support for linking users to parties
 */

/**
 * Implements hook_menu()
 */
function party_user_menu() {
  $items['admin/config/party/user'] = array(
    'title' => 'User Integration',
    'description' => 'Configure Party User Integration',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'party_user_settings_form',
    ),
    'access arguments' => array(
      'administer crm settings',
    ),
    'file' => 'party_user.admin.inc',
  );
  $items['admin/config/party/user/settings'] = array(
    'title' => 'User Integration',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'party_user_settings_form',
    ),
    'access arguments' => array(
      'administer crm settings',
    ),
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'file' => 'party_user.admin.inc',
    'weight' => -10,
  );
  $items['admin/config/party/user/sync'] = array(
    'title' => 'Sync Users',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'party_user_sync_form',
    ),
    'access arguments' => array(
      'administer crm settings',
    ),
    'type' => MENU_LOCAL_TASK,
    'file' => 'party_user.admin.inc',
  );
  return $items;
}

/**
 * Implements hook_permission()
 *
 * In this case 'own' means attached to a Party the user is also attached to.
 */
function party_user_permission() {
  $permissions = array(
    'view own party' => array(
      'title' => t('View own party'),
    ),
    'edit own party' => array(
      'title' => t('Edit own party'),
    ),
  );

  // Add permissions for each data set.
  foreach (party_get_data_set_info() as $data_set_name => $data_set) {
    $permissions['view own party attached ' . $data_set_name] = array(
      'title' => t('View own party attached %name', array(
        '%name' => $data_set['label'],
      )),
    );
    $permissions['edit own party attached ' . $data_set_name] = array(
      'title' => t('Edit own party attached %name', array(
        '%name' => $data_set['label'],
      )),
    );
    $permissions['detach own party attached ' . $data_set_name] = array(
      'title' => t('Remove own party attached %name', array(
        '%name' => $data_set['label'],
      )),
    );
    $permissions['attach own party ' . $data_set_name] = array(
      'title' => t('Add own party attached %name', array(
        '%name' => $data_set['label'],
      )),
    );
  }
  return $permissions;
}

/**
 * Implements hook_hook_info().
 *
 * @see party_hook_info().
 */
function party_user_hook_info() {

  // Acquisition hooks.
  $hooks['party_user_acquisition'] = array(
    'group' => 'party_acquisition',
  );
  return $hooks;
}

/**
 * Implements hook_ctools_plugin_directory().
 */
function party_user_ctools_plugin_directory($owner, $plugin_type) {
  if ($owner == 'ctools' && $plugin_type == 'relationships') {
    return "plugins/{$plugin_type}";
  }
}

/**
 * Menu access callback for the party user piece.
 */
function party_user_party_view_user_access($party) {

  // @todo:
  // - check user_access() for viewing user accounts
  // - check there actually is a user account to show
  // @todo:
  // nice touch, maybe: if there is no user account to show, instead offer a
  // form to connect one?
  return TRUE;
}

/**
 * Page callback for user party piece.
 */
function party_user_party_view_user($party) {

  // @todo: display the user here.
  return 'The user is shown here.';
}

/**
 * Form to edit an attached user.
 */
function party_user_form_user(&$form, &$form_state, $data_set, $delta, $party) {
  module_load_include('inc', 'user', 'user.pages');
  $form += user_profile_form($form, $form_state, $data_set
    ->getEntity($delta));
  unset($form['actions']);
}

/**
 * Validate the user data set form
 *
 * @todo: Implement
 */
function party_user_form_user_validate($element, &$form_state, $data_set, $delta, $party) {
  return TRUE;
}

/**
 * Submit the user data set form
 */
function party_user_form_user_submit($element, &$form_state, $data_set, $delta, $party) {
  $account = $data_set
    ->getEntity($delta);
  $account_unchanged = clone $account;
  $category = $element['#user_category'];
  $values = drupal_array_get_nested_value($form_state['values'], $element['#parents']);

  // This code is taken out of entity_form_submit_build_entity
  // Flatten the $form_state values for the user.
  $account_values = array();
  $account_values += isset($values['account']) ? $values['account'] : array();
  $account_values += isset($values['signature_settings']) ? $values['signature_settings'] : array();
  $account_values += isset($values['picture']) ? $values['picture'] : array();
  $values_excluding_fields = array_diff_key($account_values, field_info_instances('user', 'user'));
  foreach ($values_excluding_fields as $key => $value) {
    $account->{$key} = $value;
  }
  field_attach_submit('user', $account, $element, $form_state);
  $edit = array_intersect_key((array) $account, $account_values);
  user_save($account_unchanged, $edit, $category);
}

/**
 * Implements hook_user_view().
 *
 * Add party action links to the user.
 */
function party_user_user_view($account, $view_mode, $langcode) {
  if ($view_mode == 'party') {
    $party = party_user_get_party($account);
    $data_set_controller = $party
      ->getDataSetController('user');
    $account->content['party_actions'] = array(
      '#theme' => 'links',
      '#links' => $data_set_controller
        ->getActions($party->pid, $account->uid),
      '#attributes' => array(
        'class' => array(
          'links inline crm-set-action-links',
        ),
      ),
      '#weight' => 100,
    );
  }
}

/**
 * Implements hook_username_alter().
 */
function party_user_username_alter(&$name, $account) {
  if (!variable_get('party_user_format_username', TRUE)) {
    return;
  }
  else {
    if (!($party = party_user_get_party($account))) {
      return;
    }
    else {
      if (empty($party->label)) {
        return;
      }
    }
  }
  $name = $party->label;
}

// ========================================================================
// API Functions

/**
 * party_user_create_party_for_user
 *
 * Create a Party for a user and relate them
 *
 * @param mixed $user The user object or ID
 * @param array $options Hardcoded options to get passed to party_create
 *
 * @return Party a Party object
 *
 * @see party_create
 */
function party_user_create_party_for_user($user, $options = array()) {
  $party = party_create($options);
  if (module_exists('party_hat')) {

    // Add in our hats.
    $hats = array();
    foreach (variable_get('party_user_registration_hats', array()) as $hat_name) {
      $hats[] = $hat_name;
    }
    party_hat_hats_assign($party, $hats, FALSE);
  }
  party_save($party);
  $account = is_object($user) ? $user : user_load($user);
  $party
    ->getDataSetController('user')
    ->attachEntity($account)
    ->save();
  return $party;
}

/**
 * Get a User's Party
 *
 * @param mixed $user The user entity or uid
 *
 * @return Party a Party Object
 */
function party_user_get_party($user) {
  if (is_object($user)) {
    if (!empty($user->party_attaching_party)) {
      return party_load($user->party_attaching_party);
    }
    $uid = $user->uid;
  }
  else {
    $uid = $user;
  }
  $result = db_select('party_attached_entity', 'pae')
    ->fields('pae', array(
    'pid',
  ))
    ->condition('eid', $uid, '=')
    ->condition('data_set', 'user')
    ->execute()
    ->fetchCol();
  $party_id = reset($result);
  if (is_object($user)) {
    $user->party_attaching_party = $party_id;
  }
  return party_load($party_id);
}

/**
 * Implements hook_module_implements_alter()
 *
 * We're just going to stop profile2 from doing anything with the user page
 * for now. This should supress the thousands of errors we get on that page.
 */
function party_user_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'user_view') {
    unset($implementations['profile2']);
  }

  // Adjust the positions of our party acquisition hooks. This is important for
  // altering values.
  // The post acquisition hook needs to run first so the original acquisition
  // gets updated correctly.
  if ($hook == 'party_acquisition_post_acquisition') {
    $group = $implementations['party_user'];
    unset($implementations['party_user']);
    $implementations = array(
      'party_user' => $group,
    ) + $implementations;
  }
  elseif (substr($hook, 0, 17) == 'party_acquisition') {
    $group = $implementations['party_user'];
    unset($implementations['party_user']);
    $implementations['party_user'] = $group;
  }
}

/**
 * Implements hook_user_insert().
 *
 * If we have set up Party Acquisition, perform a party match based off of the
 * mail of the account being created. If it exists, this user will acquire the
 * party, if not we'll create a party. We will also create a user if we don't
 * use Party Acquisition but we have set that we want to create a party when a
 * user registers.
 */
function party_user_user_insert(&$edit, $account, $category) {
  if ($category == 'account') {

    // Don't acquire if the user has already been acquired.
    if (!empty($account->party_attaching_party)) {
      return;
    }

    // Find our what action to take.
    $action = variable_get('party_user_on_registration', 'nothing');
    if ($action == 'nothing') {
      return;
    }

    // Set up our acquisition.
    $values = array();
    if ($action == 'acquire') {
      $values['email'] = $account->mail;
    }

    // Clone our account.
    $account_clone = clone $account;
    unset($account_clone->is_new);

    // Set up our context.
    $context = array(
      'name' => 'party_user_registration',
      'account' => $account_clone,
      'behavior' => PartyAcquisitionInterface::BEHAVIOR_CREATE,
      'party_user' => array(
        'has_user' => FALSE,
      ),
    );
    if (module_exists('party_hat')) {

      // Make sure the party is allowed a user.
      $context['party_hat']['data_set'] = array(
        'user',
      );

      // Add in our hats.
      $context['party_hat']['add'] = variable_get('party_user_registration_hats', array());
    }

    // Fire off our acquisition.
    $party = party_acquire($values, $context, $method);
    $party
      ->save();

    // Attach our new user.
    $party
      ->getDataSetController('user')
      ->attachEntity($account_clone)
      ->save();

    // Trigger our acquisition hook and email sync.
    module_invoke_all('party_user_acquisition', $party, $account_clone, $method);
    party_user_email_sync($account_clone);
  }
}

/**
 * Implements hook_user_update().
 *
 * Performs the email synchronisation.
 */
function party_user_user_update($edit, $account, $category) {
  if ($category != 'account') {

    // We only want to deal with account, as that is where mail is.
    return;
  }
  party_user_email_sync($account);
}

/**
 * Synchronise the user email into all relevant fields.
 *
 * @param $account
 *   The account we want to synchronize.
 */
function party_user_email_sync($account) {

  // Get our array of fields to update
  $fields = variable_get('party_user_email_sync_fields', array());

  // Check that we have some fields to work with to avoid unnecessary loads
  if (count($fields) > 0 && ($party = party_user_get_party($account))) {

    // Iterate over our fields
    foreach ($fields as $info) {
      list($data_set_name, $field_name, $column) = explode(':', $info);
      party_set_data_set_value($party, $account->mail, $data_set_name, $column, $field_name);
    }

    // Save to update primary fields.
    $controller = entity_get_controller('party');
    $controller
      ->setPrimaryFields($party);
  }
}

/**
 * Party property getter for the user entity.
 *
 * Make sure the party_attaching_party property is set before trying to use it.
 *
 * @see entity_property_verbatim_get
 */
function party_user_party_property_get($data, array $options, $name, $type, $info) {
  if (empty($data->party_attaching_party)) {
    $data->party_attaching_party = db_select('party_attached_entity', 'pae')
      ->fields('pae', array(
      'pid',
    ))
      ->condition('eid', $data->uid)
      ->condition('entity_type', 'user')
      ->execute()
      ->fetchField();
  }
  return $data->party_attaching_party;
}

Functions

Namesort descending Description
party_user_create_party_for_user party_user_create_party_for_user
party_user_ctools_plugin_directory Implements hook_ctools_plugin_directory().
party_user_email_sync Synchronise the user email into all relevant fields.
party_user_form_user Form to edit an attached user.
party_user_form_user_submit Submit the user data set form
party_user_form_user_validate Validate the user data set form
party_user_get_party Get a User's Party
party_user_hook_info Implements hook_hook_info().
party_user_menu Implements hook_menu()
party_user_module_implements_alter Implements hook_module_implements_alter()
party_user_party_property_get Party property getter for the user entity.
party_user_party_view_user Page callback for user party piece.
party_user_party_view_user_access Menu access callback for the party user piece.
party_user_permission Implements hook_permission()
party_user_username_alter Implements hook_username_alter().
party_user_user_insert Implements hook_user_insert().
party_user_user_update Implements hook_user_update().
party_user_user_view Implements hook_user_view().