diff --git rpx_core.module rpx_core.module index ddb750e..45869bf 100644 --- rpx_core.module +++ rpx_core.module @@ -575,10 +575,21 @@ function _rpx_report_missing_field($entity_type, $field_name, $user_name) { * Imports Engage user profile data into profile, profile2 and user entity * fields, based on the settings for each mapping. */ -function _rpx_import_user_data() { - global $user; - $map = variable_get('rpx_profile_fields_map', array()); - $provider = $_SESSION['rpx_last_provider_info']['name']; +function _rpx_import_user_data($type = 'profile', $provider = NULL, $account = NULL, $data = NULL) { + $map = variable_get('rpx_' . $type . '_fields_map', array()); + + if (!isset($provider)) { + $provider = $_SESSION['rpx_last_provider_info']['name']; + } + + if (!isset($account)) { + global $user; + $account = $user; + } + + if (!isset($data)) { + $data = $_SESSION['rpx']; + } foreach ($map as $mid => $mapping) { // Should we try to update the field at all? @@ -586,7 +597,7 @@ function _rpx_import_user_data() { continue; } - $new_data = _rpx_data_map($_SESSION['rpx'], $mapping['fid']); + $new_data = _rpx_data_map($data, $mapping['fid']); // Only update if provider returned data for the field. if($new_data === '') { @@ -613,7 +624,7 @@ function _rpx_import_user_data() { // previous one. $prev_provider = db_select('rpx_mapping_provider') ->fields('rpx_mapping_provider', array('name')) - ->condition('uid', $user->uid) + ->condition('uid', $account->uid) ->condition('mid', $mid) ->execute() ->fetchAssoc(); @@ -634,7 +645,7 @@ function _rpx_import_user_data() { // Check that field still exists. if (!$profile) { - _rpx_report_missing_field('profile', $mapping['field'], $user->name); + _rpx_report_missing_field('profile', $mapping['field'], $account->name); continue; } @@ -643,7 +654,7 @@ function _rpx_import_user_data() { $field = db_select('profile_value') ->fields('profile_value', array('value')) ->condition('fid', $profile['fid']) - ->condition('uid', $user->uid) + ->condition('uid', $account->uid) ->execute() ->fetchAssoc(); if ($field && $field['value'] !== '') { @@ -654,7 +665,7 @@ function _rpx_import_user_data() { db_merge('profile_value') ->key(array( 'fid' => $profile['fid'], - 'uid' => $user->uid, + 'uid' => $account->uid, )) ->fields(array('value' => $new_data)) ->execute(); @@ -664,21 +675,29 @@ function _rpx_import_user_data() { // types. if(module_exists('profile2') && $mapping['set'] == 'profile2') { $entity_type = 'profile2'; - $entity = profile2_load_by_user($user->uid, $mapping['bundle']); + $entity = profile2_load_by_user($account->uid, $mapping['bundle']); } else if ($mapping['set'] == 'user') { $entity_type = 'user'; - $account = user_load($user->uid); $entity = new stdClass(); - $entity->uid = $user->uid; + $entity->uid = $account->uid; if(isset($account->{$mapping['field']})) { $entity->{$mapping['field']} = $account->{$mapping['field']}; } } + else { + // @todo: Also use this hook for profile2 and user entities ? + $entities = module_invoke_all('rpx_import_user_data', $type, $provider, $account, $data, $mapping); + $entity = reset($entities); + if (!isset($entity)) { + continue; + } + $entity_type = $entity->entityType(); + } // Check that field still exists. if (!isset($entity->{$mapping['field']})) { - _rpx_report_missing_field($entity_type, $mapping['field'], $user->name); + _rpx_report_missing_field($entity_type, $mapping['field'], $account->name); continue; } @@ -734,7 +753,7 @@ function _rpx_import_user_data() { // Record the provider's name as the last provider used in the mapping. db_merge('rpx_mapping_provider') ->key(array( - 'uid' => $user->uid, + 'uid' => $account->uid, 'mid' => $mid, )) ->fields(array('name' => $provider)) diff --git rpx_friends/rpx_friend/rpx_friend.info rpx_friends/rpx_friend/rpx_friend.info new file mode 100644 index 0000000..e05d865 --- /dev/null +++ rpx_friends/rpx_friend/rpx_friend.info @@ -0,0 +1,8 @@ +; $Id$ +name = Janrain Engage Friend entity +description = Janrain Engage Friend entity. +files[] = rpx_friend.module +files[] = rpx_friend.info.inc +files[] = rpx_friend.views.inc +package = Janrain Engage +core = 7.x diff --git rpx_friends/rpx_friend/rpx_friend.info.inc rpx_friends/rpx_friend/rpx_friend.info.inc new file mode 100644 index 0000000..4a9f4aa --- /dev/null +++ rpx_friends/rpx_friend/rpx_friend.info.inc @@ -0,0 +1,89 @@ +type]['properties']; + + $properties['id'] += array( + 'validation callback' => 'entity_property_validate_integer_positive', + ); + + $properties['user'] = array( + 'label' => t("User"), + 'type' => 'user', + 'description' => t("The owner of the friend."), + 'getter callback' => 'entity_property_getter_method', + 'setter callback' => 'entity_property_setter_method', + 'setter permission' => 'administer janrain friends', + 'required' => TRUE, + 'clear' => array('uid'), + ); + + $properties['friend'] = array( + 'label' => t("Friend"), + 'type' => 'user', + 'description' => t("The friend."), + 'getter callback' => 'entity_property_getter_method', + 'setter callback' => 'entity_property_setter_method', + 'setter permission' => 'administer janrain friends', + 'required' => TRUE, + 'clear' => array('friend_uid'), + ); +/* + $properties['provider'] = array( + 'label' => t('Provider ID'), + 'type' => 'text', // Should be token, but let's keep compatible with current rpx module. + 'description' => t('The machine-readable name of the provider.'), + 'getter callback' => 'entity_property_verbatim_get', + 'setter callback' => 'entity_property_verbatim_set', + 'setter permission' => 'administer janrain friends', + 'required' => TRUE, + ) + $properties['provider']; +*/ + $properties['rpxid'] = array( + 'label' => t('User Engage ID'), + 'type' => 'text', // Should be uri, but let's keep compatible with current rpx module. + 'description' => t('The Janrain Engage (3rd party) ID from which the friend list is received.'), + 'getter callback' => 'entity_property_verbatim_get', + 'setter callback' => 'entity_property_verbatim_set', + 'setter permission' => 'administer janrain friends', + 'required' => TRUE, + ) + $properties['rpxid']; + + $properties['friend_rpxid'] = array( + 'label' => t('Friend Engage ID'), + 'type' => 'text', // Should be uri, but let's keep compatible with current rpx module. + 'description' => t('The Janrain Engage (3rd party) ID of the friend.'), + 'getter callback' => 'entity_property_verbatim_get', + 'setter callback' => 'entity_property_verbatim_set', + 'setter permission' => 'administer janrain friends', + 'required' => TRUE, + ) + $properties['rpxid']; +/* + $properties['profile_url'] = array( + 'label' => t('Friend profile URL'), + 'type' => 'uri', + 'description' => t('The contact\'s profile URL.'), + 'getter callback' => 'entity_property_verbatim_get', + 'setter callback' => 'entity_property_verbatim_set', + 'setter permission' => 'administer janrain friends', + 'required' => TRUE, + ) + $properties['profile_url']; +*/ + unset($properties['uid']); + unset($properties['friend_uid']); + + return $info; + } +} diff --git rpx_friends/rpx_friend/rpx_friend.install rpx_friends/rpx_friend/rpx_friend.install new file mode 100644 index 0000000..dc8aea4 --- /dev/null +++ rpx_friends/rpx_friend/rpx_friend.install @@ -0,0 +1,85 @@ + 'A Janrain Engage friend.', + 'fields' => array( + 'id' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'description' => 'The internal identifier.', + ), + /* + 'provider' => array( + 'type' => 'varchar', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The machine-readable name of the provider.', + ), + */ + 'uid' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'description' => "The {users}.uid of the associated user.", + ), + 'friend_uid' => array( + 'type' => 'int', + 'not null' => FALSE, + 'default' => NULL, + 'description' => "The {users}.uid of the associated friend, if exists.", + ), + 'rpxid' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The user\'s Janrain ID.', + ), + 'friend_rpxid' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The friend\'s Janrain ID.', + ), + /* + 'profile_url' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The friend\'s profile URL.', + ), + */ + ), + 'primary key' => array('id'), + // @todo: unique keys + 'indexes' => array( + 'uid' => array('uid'), + 'friend_uid' => array('friend_uid'), + //'profile_url' => array('profile_url'), + ), + 'foreign keys' => array( + 'uid' => array('users' => 'uid'), + 'friend_uid' => array('users' => 'uid'), + 'rpxid' => array('authmap' => 'authname'), + 'friend_rpxid' => array('authmap' => 'authname'), + //'profile_url' => array('authmap' => 'authname'), + ), + 'unique keys' => array( + 'id' => array('id'), + 'uid_rpxid_friend_rpxid' => array('uid', 'rpxid', 'friend_rpxid'), + ), + ); + return $schema; +} diff --git rpx_friends/rpx_friend/rpx_friend.module rpx_friends/rpx_friend/rpx_friend.module new file mode 100644 index 0000000..9642ca5 --- /dev/null +++ rpx_friends/rpx_friend/rpx_friend.module @@ -0,0 +1,333 @@ + '2', + 'path' => drupal_get_path('module', 'rpx_friend'), + ); +} + +/** + * Implements hook_permission(). + */ +function rpx_friend_permission() { + return array( + 'administer janrain friend entity' => array( + 'title' => t('Administer Janrain Engage friend entity'), + 'description' => t('Edit and view all Janrain Engage friends entities.'), + ), + "edit own janrain friend entity" => array( + 'title' => t('Edit own Janrain Engage friend entity'), + ), + "edit any janrain friend entity" => array( + 'title' => t('Edit any Janrain Engage friend entity'), + ), + "view own janrain friend entity" => array( + 'title' => t('View own Janrain Engage friend entity'), + ), + "view any janrain friend entity" => array( + 'title' => t('View any Janrain Engage friend entity'), + ), + ); +} + +/** + * Implements hook_menu(). + */ +function rpx_friend_menu() { + $items['admin/structure/rpx_friend'] = array( + 'title' => 'Janrain friend', + 'access arguments' => array('administer janrain friend entity'), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('rpx_friend_form', 'rpx_friend'), + ); + return $items; +} + +/** + * Entity administration form. + */ +function rpx_friend_form($form, &$form_state, $bundle = array(), $op = 'edit') { + // Since there are no bundles, redirect to fields form. + drupal_goto('admin/structure/rpx_friend/edit/fields'); +} + +/** + * Implements hook_entity_info(). + */ +function rpx_friend_entity_info() { + return array( + 'rpx_friend' => array( + 'label' => t('Janrain friend'), + 'entity class' => 'RPXFriend', + 'controller class' => 'EntityAPIController', + 'module' => 'rpx_friend', + 'fieldable' => TRUE, + 'base table' => 'rpx_friend', + 'view modes' => array( + 'friend' => array( + 'label' => t('Janrain friend'), + 'custom settings' => FALSE, + ), + ), + 'entity keys' => array( + 'id' => 'id', + ), + 'bundles' => array( + 'rpx_friend' => array( + 'label' => t('Janrain friend'), + 'admin' => array( + 'path' => 'admin/structure/rpx_friend/edit', + 'access arguments' => array('administer janrain friend entity'), + ), + ), + ), + 'label callback' => 'entity_class_label', + 'uri callback' => 'entity_class_uri', + 'metadata controller class' => 'RPXFriendMetadataController', + 'access callback' => 'rpx_friend_access', + ), + ); +} + +/** + * Implements hook_user_delete(). + */ +function rpx_friend_user_delete($account) { + foreach (rpx_friend_load_by_user($account) as $friend) { + rpx_friend_delete($friend); + // @todo: reverse friend deletion. + } +} + +/** + * Implements hook_user_cancel(). + */ +function rpx_friend_user_cancel($edit, $account, $method) { + switch ($method) { + case 'user_cancel_reassign': + foreach (rpx_friend_load_by_user($account) as $friend) { + rpx_friend_delete($friend); + // @todo: reverse friend deletion. + } + break; + } +} + +/** + * Implements hook_rpx_import_user_data(). + */ +function rpx_friend_rpx_import_user_data($type, $provider, $account, $data, $mapping) { + if ($type == 'friends' && $mapping['set'] == 'rpx_friend') { + $params = array( + 'uid' => $account->uid, + 'rpxid' => $data['rpxid'], + 'friend_rpxid' => $data['friend_rpxid'], + ); + + $existing = rpx_friend_load_multiple(FALSE, $params); + if (!empty($existing)) { + return reset($existing); + } + + $entity = rpx_friend_create($params + array( + 'bundle' => $mapping['bundle'], + 'user' => $account, + 'friend' => $data['friend'], + )); + $entity->{$mapping['field']} = array(); + $entity->save(); + return $entity; + } +} + +/** + * Implements hook_rpx_friends_retrieve(). + */ +function rpx_friend_rpx_friends_retrieve($rpxid, $account, $results) { + $settings = _rpx_friends_settings(); + + if ($settings['delete']) { + $friends = rpx_friend_load_multiple(FALSE, array('uid' => $account->uid, 'rpxid' => $rpxid)); + + foreach ($results['response']['entry'] as $entry) { + $found = FALSE; + foreach ($friends as $key => $friend) { + if ($entry['id'] == $friend->friend_rpxid) { + unset($friends[$key]); + break; + } + } + } + + rpx_friend_delete_multiple(array_keys($friends)); + } +} + +/** + * Fetch a friend object. + * + * @param $id + * Integer specifying the friend id. + * @param $reset + * A boolean indicating that the internal cache should be reset. + * @return + * A fully-loaded $friend object or FALSE if it cannot be loaded. + * + * @see rpx_friend_load_multiple() + */ +function rpx_friend_load($id, $reset = FALSE) { + $friend = rpx_friend_load_multiple(array($id), array(), $reset); + return reset($friend); +} + +/** + * Load multiple friends based on certain conditions. + * + * @param $ids + * An array of friend IDs. + * @param $conditions + * An array of conditions to match against the {rpx_friend} table. + * @param $reset + * A boolean indicating that the internal cache should be reset. + * @return + * An array of friend objects, indexed by id. + * + * @see entity_load() + * @see rpx_friend_load() + * @see rpx_friend_load_by_user() + */ +function rpx_friend_load_multiple($ids = array(), $conditions = array(), $reset = FALSE) { + return entity_load('rpx_friend', $ids, $conditions, $reset); +} + +/** + * Fetch friends by account. + * + * @param $account + * The user account to load friends for, or its uid. + * @return + * An array of friends owned by the user. + * + * @see rpx_friend_load_multiple() + */ +function rpx_friend_load_by_user($account) { + $cache = &drupal_static(__FUNCTION__, array()); + $uid = is_object($account) ? $account->uid : $account; + + if (!isset($cache[$uid])) { + $friends = rpx_friend_load_multiple(FALSE, array('uid' => $uid)); + $cache[$uid] = array_keys($friends); + return $friends; + } + return rpx_friend_load_multiple($cache[$uid]); +} + +/** + * Deletes a friend. + * + * @param $friend + * The friend object. + */ +function rpx_friend_delete(RPXFriend $friend) { + $friend->delete(); +} + +/** + * Delete multiple friends. + * + * @param $ids + * An array of friend IDs. + */ +function rpx_friend_delete_multiple(array $ids) { + entity_get_controller('rpx_friend')->delete($ids); +} + +/** + * Create a new friend object. + * + * @param $values + * An array of values to set for the created friend object. + */ +function rpx_friend_create(array $values) { + return new RPXFriend($values); +} + +/** + * Saves a friend to the database. + * + * @param $friend + * The friend object. + */ +function rpx_friend_save(RPXFriend $friend) { + return $friend->save(); +} + +/** + * The class used for friend entities. + */ +class RPXFriend extends Entity { + + /** + * Constructor. + */ + public function __construct($values = array()) { + if (isset($values['user'])) { + $this->setUser($values['user']); + unset($values['user']); + } + + if (isset($values['friend'])) { + $this->setFriend($values['friend']); + unset($values['friend']); + } + + parent::__construct($values, 'rpx_friend'); + } + + /** + * Returns the user owning this friend. + */ + public function user() { + return user_load($this->uid); + } + + /** + * Sets a new user owning this friend. + */ + public function setUser($account) { + if (is_object($account)){ + $this->uid = $account->uid; + } + else { + $this->uid = (int) $account; + } + } + + /** + * Returns the friend. + */ + public function friend() { + return user_load($this->friend_uid); + } + + /** + * Sets a new friend. + */ + public function setFriend($account) { + if (is_object($account)){ + $this->friend_uid = $account->uid; + } + else { + $this->friend_uid = (int) $account; + } + } +} diff --git rpx_friends/rpx_friend/rpx_friend.rules.inc rpx_friends/rpx_friend/rpx_friend.rules.inc new file mode 100644 index 0000000..2e900ff --- /dev/null +++ rpx_friends/rpx_friend/rpx_friend.rules.inc @@ -0,0 +1,33 @@ + array( + 'label' => t('Friend entity exists'), + 'parameter' => array( + 'rpx_friend_info' => array('type' => 'rpx_friend_info', 'label' => t('Janrain Engage friend info')), + ), + 'group' => t('Janrain Engage'), + ), + ); +} + +/** + * Callback for rpx_friend_rules_condition_info(). + */ +function rpx_friend_rules_condition_callback_friend_exists($info) { + $query = db_select('rpx_friend'); + $query->condition('uid', $info['rpx']->user->uid); + $query->condition('rpxid', $info['rpx']->id); + $query->condition('profile_url', $info['profile_url']); + $exists = $query->range(0, 1)->countQuery()->execute()->fetchField(); + return ($exists == 1); +} diff --git rpx_friends/rpx_friend/rpx_friend.views.inc rpx_friends/rpx_friend/rpx_friend.views.inc new file mode 100644 index 0000000..2465da3 --- /dev/null +++ rpx_friends/rpx_friend/rpx_friend.views.inc @@ -0,0 +1,34 @@ + array( + 'label' => t('Authmap'), + 'base' => 'authmap', + 'base field' => 'authname', + 'relationship field' => 'profile_url', + 'handler' => 'views_handler_relationship', + ), + 'title' => t('Authmap of the friend'), + 'help' => t('Relate authmap to user account.'), + ); + $data['rpx_friend']['friend'] = array( + 'relationship' => array( + 'label' => t('Friend'), + 'base' => 'user', + 'base field' => 'uid', + 'relationship field' => 'friend_uid', + 'handler' => 'views_handler_relationship', + ), + 'title' => t('Friend account'), + 'help' => t('Relate to friend account.'), + ); +} diff --git rpx_friends/rpx_friends.admin.inc rpx_friends/rpx_friends.admin.inc new file mode 100644 index 0000000..c949103 --- /dev/null +++ rpx_friends/rpx_friends.admin.inc @@ -0,0 +1,339 @@ +fetchAllAssoc('fid', PDO::FETCH_ASSOC); + + $form['settings'] = array( + '#type' => 'vertical_tabs', + ); + + // Existing users. + if (module_exists('user_reference') || module_exists('user_relationships') || module_exists('flag')) { + $form['#tree'] = TRUE; + $form['existing'] = array( + '#tree' => TRUE, + '#type' => 'fieldset', + '#title' => t('Existing users'), + '#group' => 'settings', + ); + $form['existing']['module'] = array( + '#type' => 'select', + '#options' => array(), + '#empty_option' => t('- Select a module -'), + '#default_value' => $settings['existing']['module'], + '#title' => t('Module to use when a friend correponds to an existing user'), + '#description' => t('Choose one of the supported modules to relate friends to the user. Currently, User Reference, User Relationships and Flag are supported.'), + '#weight' => 10, + ); + + // Populate fields catalog if user_reference module exists. + if (module_exists('user_reference')) { + $form['existing']['module']['#options']['user_reference'] = t('User Reference'); + + // Only profile2 and user modules are supported here since user_reference is + // only available on real entities. + $catalog = _rpx_drupal_field_catalog(array('profile2', 'user')); + foreach ($catalog as $entity_name => $entity) { + foreach ($entity['bundles'] as $bundle_name => $bundle) { + foreach ($bundle['fields'] as $field_name => $field_label) { + $field_info = field_info_field($field_name); + if ($field_info['module'] != 'user_reference') { + unset($catalog[$entity_name]['bundles'][$bundle_name]['fields'][$field_name]); + } + } + } + } + + // We fake the mid mechanism used by rpx_ui.js. + $form['existing']['user_reference'] = array( + '#type' => 'fieldset', + '#tree' => TRUE, + '#title' => t('Field'), + '#weight' => 11, + '#theme' => 'rpx_friends_mapping_existing_user_reference_form', + '#states' => array( + 'visible' => array('select[name="existing[module]"]' => array('value' => 'user_reference')), + ), + 'field_set' => array( + '#type' => 'select', + '#title' => t('Fieldset'), + '#title_display' => 'invisible', + '#options' => _rpx_drupal_field_options($catalog, 'set'), + '#default_value' => $settings['existing']['user_reference']['field_set'], + '#empty_option' => t('- Select a fieldset -'), + '#description' => t('Module or entity.'), + '#attributes' => array('class' => array('field-set-select', 'mid-user_reference')), + ), + 'field_bundle' => array( + '#type' => 'select', + '#title' => t('Fieldset type'), + '#title_display' => 'invisible', + '#options' => _rpx_drupal_field_options($catalog, 'bundle'), + '#default_value' => $settings['existing']['user_reference']['field_bundle'], + '#empty_option' => t('- Select a type -'), + '#description' => t('Fieldset type.'), + '#attributes' => array('class' => array('field-bundle-select', 'mid-user_reference')), + ), + 'field' => array( + '#type' => 'select', + '#title' => t('Field'), + '#title_display' => 'invisible', + '#options' => $catalog, + '#default_value' => $settings['existing']['user_reference']['field'], + '#empty_option' => t('- Select a field -'), + '#description' => t('Field.'), + '#attributes' => array('class' => array('field-select', 'mid-user_reference')), + ), + '#attached' => array( + 'js' => array( + drupal_get_path('module', 'rpx_ui') . '/rpx_ui.js', + array( + 'type' => 'setting', + 'data' => array('catalog' => $catalog, 'map' => array('user_reference' => array()), 'rpx_fields' => array()), + ), + ), + ), + ); + } + + // Populate relationships if user_relationships module exists. + if (module_exists('user_relationships')) { + $form['existing']['module']['#options']['user_relationships'] = t('User Relationships'); + + $options = array(); + $relationship_types = user_relationships_types_load(); + + foreach ($relationship_types as $type) { + $options[$type->rtid] = $type->name; + } + + $form['existing']['user_relationships'] = array( + '#type' => 'fieldset', + '#tree' => TRUE, + '#title' => t('User Relationships'), + '#weight' => 100, + '#states' => array( + 'visible' => array('select[name="existing[module]"]' => array('value' => 'user_relationships')), + ), + ); + $form['existing']['user_relationships']['type'] = array( + '#type' => 'radios', + '#title' => t('Relationship type'), + '#options' => $options, + '#default_value' => $settings['existing']['user_relationships']['type'], + '#empty_option' => t('- Select a type -'), + '#description' => t('Choose a relation type.'), + ); + $form['existing']['user_relationships']['approve'] = array( + '#type' => 'checkbox', + '#title' => t('Automatically approve relationship'), + '#default_value' => $settings['existing']['user_relationships']['approve'], + '#description' => t('Whether the relation should be automatically approved or not.'), + ); + } + + // Populate flags if flag module exists. + if (module_exists('flag')) { + $form['existing']['module']['#options']['flag'] = t('Flag'); + + $options = array(); + $flags = flag_get_flags(); + + foreach ($flags as $flag) { + if ($flag->content_type == 'user') { + $options[$flag->fid] = $flag->title; + } + } + + $form['existing']['flag'] = array( + '#type' => 'fieldset', + '#tree' => TRUE, + '#title' => t('Flag'), + '#weight' => 100, + '#states' => array( + 'visible' => array('select[name="existing[module]"]' => array('value' => 'flag')), + ), + ); + $form['existing']['flag']['name'] = array( + '#type' => 'radios', + '#title' => t('Flag'), + '#options' => $options, + '#empty_option' => t('- Select a flag -'), + '#default_value' => $settings['existing']['flag']['name'], + '#description' => t('Choose a user flag.'), + ); + $form['existing']['flag']['skip_permission_check'] = array( + '#type' => 'checkbox', + '#title' => t('Skip permission check'), + '#default_value' => $settings['existing']['flag']['skip_permission_check'], + '#description' => t('Whether the permission to create this flag for the user should be checked or not.'), + ); + } + } + + // Non existing users. + if (module_exists('rpx_friend')) { + $form['#tree'] = TRUE; + $form['non_existing'] = array( + '#tree' => TRUE, + '#type' => 'fieldset', + '#title' => t('Friend entity'), + '#group' => 'settings', + ); + $form['non_existing']['create'] = array( + '#type' => 'checkbox', + '#title' => t('Create an entity for non-existing users'), + '#default_value' => $settings['non_existing']['create'], + '#weight' => -10, + '#description' => t('If checked, a Friend entity will be created.'), + ); + $form['non_existing']['mapping'] = array( + '#type' => 'fieldset', + '#tree' => TRUE, + '#title' => t('Fields'), + '#weight' => 0, + '#theme' => 'rpx_friends_mapping_non_existing_form', + '#states' => array( + 'visible' => array('input[name="non_existing[create]"]' => array('checked' => TRUE)), + ), + ); + + foreach ($map as $mid => $mapping) { + $form['non_existing']['mapping'][$mid] = array( + '#tree' => TRUE, + 'fid' => array( + '#type' => 'select', + '#title' => t('Engage field'), + '#title_display' => 'invisible', + '#options' => _rpx_engage_field_options(), + '#empty_option' => t('- Select a data field -'), + '#description' => t('Data path.'), + '#default_value' => isset($mapping['fid']) ? $mapping['fid'] : NULL, + ), + 'separator' => array( + '#markup' => '=>' + ), + 'field' => array( + '#type' => 'select', + '#title' => t('Field'), + '#title_display' => 'invisible', + '#options' => array(), + '#empty_option' => t('- Select a field -'), + '#description' => t('Field.'), + '#default_value' => isset($mapping['field']) ? $mapping['field'] : NULL, + ), + 'edit' => array( + '#type' => 'link', + '#title' => t('edit'), + '#href' => "admin/config/people/rpx/mapping/friends/edit/$mid", + ), + 'set' => array( + '#type' => 'value', + '#value' => 'rpx_friend', + ), + 'bundle' => array( + '#type' => 'value', + '#value' => 'rpx_friend', + ), + ); + foreach (field_info_instances('rpx_friend', 'rpx_friend') as $field_name => $field) { + $form['non_existing']['mapping'][$mid]['field']['#options'][$field_name] = $field['label']; + } + } + } + + if (isset($form)) { + $form['actions'] = array('#type' => 'actions'); + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + } + else { + drupal_set_message(t('There are no module enabled for friends creation. You need at least Janrain Engage Friend entity module for non-existing users or User Reference, User Relationships or Flag modules for existing friends support.'), 'warning'); + } + + return $form; +} + +/** + * Submit handler for friends mapping. + * + * @see rpx_friends_mapping_settings_form() + */ +function rpx_friends_mapping_settings_form_submit($form, &$form_state) { + $values = $form_state['values']; + if (isset($values['non_existing']['mapping'])) { + $mapping = $values['non_existing']['mapping']; + variable_set('rpx_friends_fields_map', $mapping); + unset($values['non_existing']['mapping']); + } + variable_set('rpx_friends_mapping', $values); +} + +/** + * Theme User reference field picker. + * + * @ingroup themeable + */ +function theme_rpx_friends_mapping_existing_user_reference_form($variables) { + $form = $variables['form']; + + $rows = array(); + $row = array(); + foreach (element_children($form) as $key) { + $row[] = drupal_render($form[$key]); + } + $rows[] = array('data' => $row); + $header = array(t('Entity'), t('Bundle'), t('Field')); + + $output = drupal_render_children($form); + $output .= theme('table', array('header' => $header, 'rows' => $rows)); + + return $output; +} + +/** + * Theme Engage friend field mapping form. + * + * @ingroup themeable + */ +function theme_rpx_friends_mapping_non_existing_form($variables) { + $form = $variables['form']; + + $rows = array(); + foreach (element_children($form) as $key) { + $row = array(); + foreach (element_children($form[$key]) as $subkey) { + if ($subkey == 'set' || $subkey == 'bundle') { + continue; + } + $row[] = drupal_render($form[$key][$subkey]); + } + $rows[] = array('data' => $row); + } + + $header = array(); + $header[] = array('data' => t('Engage Data Field')); + $header[] = array('data' => ''); + $header[] = array('data' => t('Friend field')); + $header[] = array('data' => t('Operations')); + + $output = drupal_render_children($form); + $output .= theme('table', array('header' => $header, 'rows' => $rows)); + + return $output; +} diff --git rpx_friends/rpx_friends.info rpx_friends/rpx_friends.info new file mode 100644 index 0000000..2a756c7 --- /dev/null +++ rpx_friends/rpx_friends.info @@ -0,0 +1,7 @@ +; $Id$ +name = Janrain Engage Friends +description = Janrain Engage Friends support. +files[] = rpx_friends.module +dependencies[] = "rpx_core" +package = Janrain Engage +core = 7.x diff --git rpx_friends/rpx_friends.module rpx_friends/rpx_friends.module new file mode 100644 index 0000000..1116014 --- /dev/null +++ rpx_friends/rpx_friends.module @@ -0,0 +1,396 @@ +' . t('Configure how friends should be created and configure mapping of friends fields to the 3rd party friends data returned by Engage.') . '
'. t('To create friends for non-existing users, you need to enable Janrain Engage Friend entity module.') . '
'. t('To relate existing users as friends, you need at least one of the following modules: User Reference, User Relationships or Flag.') . '