party_user.module in Party 8.2
Same filename and directory in other branches
Support for linking users to parties
File
modules/party_user/party_user.moduleView source
<?php
/**
* @file
* Support for linking users to parties
*/
/**
* Implements hook_party_data_set_info()
*/
function party_user_party_data_set_info() {
$sets['user'] = array(
'label' => t("User account"),
'entity type' => 'user',
'class' => 'PartyUserDataSet',
'singleton' => TRUE,
'max cardinality' => 1,
'admin' => array(
'edit' => 'admin/config/people/accounts',
'manage fields' => 'admin/config/people/accounts/fields',
'manage display' => 'admin/config/people/accounts/display',
),
'form callback' => 'party_user_form_user',
// Provide a piece corresponding to the data set.
'piece' => array(
'path' => 'user',
'maker' => 'core',
// @todo: these don't have any effect yet.
// @see http://drupal.org/node/1669774.
'weight' => -8,
),
'actions' => array(
'attach' => array(
'controller' => 'PartyUserDataSetUIAttach',
'action label' => 'Attach existing user',
),
'add' => array(
'controller' => 'PartyUserDataSetUIAdd',
'action label' => 'Add a new user',
),
),
// Some of our permissions require a warning.
'permissions' => array(
// Attaching a user account to a party potentially grants a new user
// access to data on that party.
'attach' => array(
'restrict access' => TRUE,
),
'edit' => array(
'restrict access' => TRUE,
),
),
);
return $sets;
}
/**
* 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_party_access()
*/
function party_user_party_access($op, $party, $data_set, $account) {
// If we haven't been passed a party, it's outside of the scope of these
// checks.
if (!isset($party)) {
return NULL;
}
// Prepare the data set controller.
$controller = party_get_crm_controller($party, 'user');
// Deny access for party deletions if the configuration says so.
if (empty($data_set) && $op == 'delete' && count($controller
->getEntityIds()) && variable_get('party_user_party_delete_action', 'disallow') == 'disallow') {
return FALSE;
}
// Check if this is their own party by getting the controller and checking
// that $account is one of the attached entities for this party.
if (!in_array($account->uid, $controller
->getEntityIds())) {
return NULL;
}
// Set the data_set_name
if (isset($data_set)) {
$data_set_name = $data_set['set_name'];
}
// If we're looking at permission for a particular data set we check these.
if (isset($data_set_name)) {
// Determine which permission we need to check.
switch ($op) {
case 'view':
$permission_string = 'view own party attached ' . $data_set_name;
break;
case 'edit':
$permission_string = 'edit own party attached ' . $data_set_name;
break;
case 'detach':
$permission_string = 'detach own party attached ' . $data_set_name;
break;
case 'attach':
case 'add':
$permission_string = 'attach own party ' . $data_set_name;
break;
}
}
else {
// If we're not being asked about attachments, just use plain permissions.
switch ($op) {
case 'view':
$permission_string = 'view own party';
break;
case 'edit':
$permission_string = 'edit own party';
break;
}
}
// If we have a valid permission, check it. In this hook we only grant access
// with the permissions, not deny it. In other words, the permission
// 'view party attached foo' is sufficient but not neccessary, it is
// advisable to use these blanket permissions sparingly.
// @todo: add explanation of this to the party_access() docblock.
if (isset($permission_string) && user_access($permission_string, $account)) {
return TRUE;
}
// If we get here - say nothing.
return NULL;
}
/**
* Implements hook_ctools_plugin_directory().
*/
function party_user_ctools_plugin_directory($owner, $plugin_type) {
if ($owner == 'party' || $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_get_crm_controller($party, '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);
}
party_save($party);
$data_set_controller = party_get_crm_controller($party, 'user');
$account = is_object($user) ? $user : user_load($user);
$data_set_controller
->attachEntity($account);
$data_set_controller
->save();
// This will fail if a plugin that relies on anything other than user is used
$party = party_save($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)) {
$user = $user->uid;
}
$result = db_select('party_attached_entity', 'pae')
->fields('pae', array(
'pid',
))
->condition('eid', $user, '=')
->condition('data_set', 'user')
->execute()
->fetchCol();
$party_id = reset($result);
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']);
}
}
/**
* 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') {
$action = variable_get('party_user_on_registration', 'nothing');
if ($action == 'acquire') {
// Perform our matching query and load the party.
$query = db_select('party');
$query
->addField('party', 'pid');
$query
->condition('party.email', $account->mail);
$query
->range(0, 1);
$party = $query
->execute()
->fetchField();
// Attempt to load the party.
if ($party) {
$party = party_load($party);
}
else {
// Indicate that we need to create a party.
$action = 'create';
}
}
// If we need to create a party, lets do it.
if ($action == 'create') {
$party = party_create();
party_save($party);
}
if (!empty($party)) {
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);
}
// Get our controller and attach the user.
$controller = party_get_crm_controller($party, 'user');
// Check there isn't already an account attached.
$user_ids = $controller
->getEntityIds();
if (empty($user_ids)) {
$account_clone = clone $account;
unset($account_clone->is_new);
$controller
->attachEntity($account_clone);
$controller
->save();
}
module_invoke_all('party_user_acquisition', $party, $user, $action);
}
}
}
/**
* 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;
}
// 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
$data_sets = array();
foreach ($fields as $data_set => $field) {
list($data_set, $field) = explode(':', $field);
if (!isset($data_sets[$data_set])) {
// Load the entity, assume there's only one
$data_sets[$data_set] = reset(party_get_attached_entities($party, $data_set));
}
if ($data_sets[$data_set]) {
// Update the field and save
$data_sets[$data_set]->{$field}[LANGUAGE_NONE][0]['value'] = $account->mail;
$data_sets[$data_set]
->save();
}
}
}
}
Functions
Name | 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_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_menu | Implements hook_menu() |
party_user_module_implements_alter | Implements hook_module_implements_alter() |
party_user_party_access | Implements hook_party_access() |
party_user_party_data_set_info | Implements hook_party_data_set_info() |
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(). |