diff --git realname.admin.inc realname.admin.inc index 7bd2828..7826566 100644 --- realname.admin.inc +++ realname.admin.inc @@ -215,7 +215,6 @@ function realname_admin_bypass_submit($form, &$form_state) { function realname_admin_module($form_state) { $form = array(); // Get the list of modules we support. - include_once(drupal_get_path('module', 'realname') .'/realname_supported.inc'); $supported_modules = realname_supported_modules(); $choices = $show_types = array(); @@ -274,9 +273,13 @@ function realname_admin_module_submit($form, &$form_state) { $show_types = $form_state['values']['show_types']; if ($show_types[$module]) { - include_once(drupal_get_path('module', 'realname') .'/realname_'. $module .'.inc'); - // This module uses types, so let's see what types are allowed. - $types = call_user_func('realname_'. $module .'_get_types'); + $module_info = realname_supported_modules($module); + if (isset($module_info['file'])) { + $path = !empty($module_info['path']) ? $module_info['path'] : drupal_get_path('module', $module); + require_once($path .'/'. $module_info['file']); + } + // This module uses types, so let's see what types are allowed. + $types = (array) module_invoke($module, 'realname_get_types'); if (count($types) > 1) { $form_state['storage']['types'] = $types; return; @@ -297,14 +300,29 @@ function realname_admin_module_submit($form, &$form_state) { function realname_admin_fields() { $form = array(); - $current = variable_get('realname_fields', array()); $module = variable_get('realname_profile_module', NULL); - $type = variable_get('realname_profile_type', NULL); // Do we have a module set yet? if (!$module) { drupal_goto('admin/user/realname/module'); } + $module_info = $module ? realname_supported_modules($module) : NULL; + if (isset($module_info['fields']) && !$module_info['fields']) { + $form['heading'] = array( + '#type' => 'item', + '#value' => t("You are using the %module module to provide data and it doesn't utilize fields.", array('%module' => $module)), + ); + return $form; + } + + if (isset($module_info['file'])) { + $path = !empty($module_info['path']) ? $module_info['path'] : drupal_get_path('module', $module); + require_once($path .'/'. $module_info['file']); + } + $current = variable_get('realname_fields', array()); + $type = (!isset($module_info['type']) || !$module_info['type']) ? variable_get('realname_profile_type', NULL) : NULL; + $profile_fields = (array) module_invoke($module, 'realname_get_fields', $current, $type); + $what = t('You are using the %module module to provide fields.', array('%module' => $module)); if ($type) { $what .= t('The %type type is the source of data.', array('%type' => $type)); @@ -315,8 +333,6 @@ function realname_admin_fields() { '#value' => $what, ); - include_once(drupal_get_path('module', 'realname') .'/realname_'. $module .'.inc'); - $profile_fields = call_user_func('realname_'. $module .'_get_fields', $current, $type); $fields = $profile_fields['fields']; uasort($fields, '_realname_sort'); $links = $profile_fields['links']; diff --git realname.api.php realname.api.php new file mode 100644 index 0000000..0b928f8 --- /dev/null +++ realname.api.php @@ -0,0 +1,172 @@ + 'Content Profile', + 'types' => TRUE, + 'fields' => TRUE, + 'file' => 'realname_content_profile.inc', + 'path' => drupal_get_path('module', 'realname'), + ); +} + +/** + * Loads the profile fields. + * + * @param $account + * An user object. + * @param $type + * The type used - if supported by the module. + */ +function hook_load_profile(&$account, $type = NULL) { + $profile = content_profile_load($type, $account->uid); + if (!$profile) { + return; + } + $fields = content_fields(NULL, $type); + foreach ($fields as $field_name => $field_attributes) { + if (isset($profile->$field_name)) { + $values = array(); + $contents = $profile->$field_name; + foreach ($contents as $content) { + if (isset($content['value'])) { + $values[] = $content['value']; + } + else { + $values[] = content_format($field_name, $content); + } + } + if (empty($account->{$field_name})) { + switch (count($values)) { + case 0: + $account->{$field_name} = NULL; + break; + case 1: + $account->{$field_name} = $values[0]; + break; + default: + $account->{$field_name} = $values; + } + } + } + } +} + +/** + * Gets available types. + * + * Supplies the types supported by the module if the module supports types. + * + * @return + * An array keyed by type with info. + */ +function hook_realname_get_types() { + return content_profile_get_types('names'); +} + +/** + * Gets available fields. + * + * Supplies the fields supported by the module if the module supports fields. + * + * @param $current + * An array with the currently used fields keyed by field. + * @param $type + * An array containing the current type. + * @return + * An associative array with two keys: + * - "fields": Required. An array keyed by field name of fields as + * associative arrays containing: + * - "title": The title of the field + * - "weight": The weight of the field + * - "selected": A boolean value of whether the field is slected or not + * - "links": Required. An array of field labels keyed by field name + */ +function hook_realname_get_fields($current, $type = NULL) { + $fields = $links = array(); + $all_fields = content_fields(NULL, $type); + if ($all_fields) { + foreach ($all_fields as $field_name => $field_attributes) { + // If it's not they type we are looking for, then skip the field. + if ($field_attributes['type_name'] != $type) { + continue; + } + switch ($field_attributes['type']) { + case 'text': + if ($field_attributes['multiple']) { + drupal_set_message(t('The RealName module does not currently support fields with multiple values, such as @fld.', array('@fld' => $field_name)), 'warning'); + } + else { + $selected = array_key_exists($field_name, $current); + $fields[$field_name] = array( + 'title' => $field_attributes['widget']['label'], + 'weight' => $selected ? $current[$field_name] : 0, + 'selected' => $selected, + ); + } + break; + + case 'link': + $links[$field_name] = $field_attributes['widget']['label']; + } + } + } + else { + drupal_set_message(t('The !type content type has no fields to use.', array('!type' => $type)), 'error'); + } + + if (variable_get('realname_use_title', FALSE)) { + $fields['title'] = array( + 'title' => t('Node title'), + 'weight' => isset($current['title']) ? $current['title']['weight'] : 0, + 'selected' => array_key_exists('title', $current), + ); + } + + return array('fields' => $fields, 'links' => $links); +} + +/** + * Gets a name for a user + * + * Modules not supporting fields for name data has to + * implement this hook instead + * + * @param $account + * An user object. + * @return + * A string with the name or NULL. + */ +function hook_realname_make($account) { + $info = _connector_information_fetch($account); + return !empty($info['real name']) ? $info['real name'] : NULL; +} \ No newline at end of file diff --git realname.module realname.module index 5c3ecdf..83b7c87 100644 --- realname.module +++ realname.module @@ -464,6 +464,12 @@ function realname_user($op, &$edit, &$account, $category = NULL) { case 'insert': case 'after_update': + if ($module = variable_get('realname_profile_module', NULL)) { + $module_info = realname_supported_modules($module); + if (isset($module_info['cache']) && !$module_info['cache']) { + return; + } + } $account->realname = _realname_make_name($account); // If we delete it first, then drupal_write_record is always an insert. db_query("DELETE FROM {realname} WHERE uid = %d", $account->uid); @@ -763,6 +769,47 @@ function realname_privatemsg_autocomplete($string) { //* Module Functions //******************************************************************** +function _realname_include() { + static $not_run = TRUE; + + if ($not_run) { + $path = drupal_get_path('module', 'realname'); + if (module_exists('content_profile')) { + require_once("$path/realname_content_profile.inc"); + } + if (module_exists('profile')) { + require_once("$path/realname_profile.inc"); + } + $not_run = TRUE; + } +} + +function realname_supported_modules($module = NULL) { + static $modules; + + _realname_include(); + + if (!isset($modules)) { + foreach (module_implements('realname') as $value) { + $options = call_user_func($value .'_realname'); + if (isset($options) && is_array($options)) { + $modules[$value] = $options; + } + } + } + + if ($module) { + if (array_key_exists($module, $modules)) { + return $modules[$module]; + } + else { + return FALSE; + } + } + + return $modules; +} + /** * Retreive calculated user name. Try static cache first, DB next and on failure call * helper function to calculate realname and populate DB. @@ -788,7 +835,13 @@ function realname_make_name(&$account) { return $users[$account->uid]; } + if ($module = variable_get('realname_profile_module', NULL)) { + $module_info = realname_supported_modules($module); + } $result = _realname_make_name($account); + if (isset($module_info['cache']) && !$module_info['cache']) { + return $result; + } if (empty($result)) { return $account->name; } @@ -811,41 +864,65 @@ function realname_make_name(&$account) { * The constructed "real name" string. */ function _realname_make_name(&$account) { - static $fields, $pattern_saved, $homepage, $use_theme, $type, $module, $profile_privacy; - $users = &drupal_static('users',array()); + static $fields, $pattern_saved, $homepage, $use_theme, $type, $module, $module_info, $profile_privacy; $links = &drupal_static('links',array()); $edit = &drupal_static('edit',array()); // Get our controlling variables (static makes it once per page load). - if (!isset($fields)) { - $fields = variable_get('realname_fields', array()); - // Are there any fields assigned yet? - if (!$fields) { - // No, so just return the name. - return $account->name; - } - $pattern_saved = variable_get('realname_pattern', ' '); - $homepage = variable_get('realname_homepage', ''); - $use_theme = variable_get('realname_theme', TRUE); + if (!isset($module)) { $module = variable_get('realname_profile_module', NULL); - $type = variable_get('realname_profile_type', NULL); - $profile_privacy = module_exists('profile_privacy'); - if ($module && module_exists($module)) { - include_once(drupal_get_path('module', 'realname') . '/realname_' . $module . '.inc'); - } - else { - drupal_set_message(t('No module is available for RealName.'), 'error'); - return $account->name; + if ($module) { + $module_info = realname_supported_modules($module); + if (!$module_info || !module_exists($module)) { + unset($module_info); + $module = FALSE; + } + else { + if (isset($module_info['file'])) { + $path = !empty($module_info['path']) ? $module_info['path'] : drupal_get_path('module', $module); + require_once($path .'/'. $module_info['file']); + } + if (!isset($module_info['fields']) || $module_info['fields']) { + $fields = variable_get('realname_fields', array()); + // Are there any fields assigned yet? + if (!$fields) { + // No, so just return the name. + return $account->name; + } + $pattern_saved = variable_get('realname_pattern', ' '); + } + else { + $fields = FALSE; + } + $homepage = variable_get('realname_homepage', ''); + $use_theme = variable_get('realname_theme', TRUE); + if (isset($module_info['type']) && $module_info['type']) { + $type = variable_get('realname_profile_type', NULL); + } + else { + $type = FALSE; + } + $profile_privacy = module_exists('profile_privacy'); + } } } - $pattern = $pattern_saved; - // Has the module been set up yet? - if ($fields) { + if (!$module) { + drupal_set_message(t('No module is available for RealName.'), 'error'); + $string = $account->name; + } + else if (is_array($fields) && empty($fields)) { + $string = $account->name; + } + else if ($fields === FALSE) { + $string = module_invoke($module, 'realname_make', $account); + } + else if ($fields) { + $pattern = $pattern_saved; + // Has the profile been loaded? if (!isset($account->{key($fields)})) { - $load_func = $module . '_load_profile'; - if (!function_exists($load_func)) { + if (!module_hook($module, 'load_profile')) { drupal_set_message(t('The profile load function (!module) was not found.', array('!module' => $load_func)), 'error'); return $account->name; } @@ -890,11 +967,12 @@ function _realname_make_name(&$account) { } $string = trim(strtr($pattern, $stuff)); - $users[$account->uid] = $string; } - else { + + if (empty($string)) { $string = $account->name; } + return html_entity_decode(filter_xss_admin($string)); } diff --git realname_content_profile.inc realname_content_profile.inc index 0f7f649..26fa7c9 100644 --- realname_content_profile.inc +++ realname_content_profile.inc @@ -6,6 +6,19 @@ */ /** + * Implementation of hook_realname(). + */ +function content_profile_realname() { + return array( + 'name' => 'Content Profile', + 'types' => TRUE, + 'fields' => TRUE, + 'file' => 'realname_content_profile.inc', + 'path' => drupal_get_path('module', 'realname'), + ); +} + +/** * Implementation of hook_profile_load(); */ function content_profile_load_profile(&$account, $type = NULL) { @@ -45,11 +58,11 @@ function content_profile_load_profile(&$account, $type = NULL) { // $account->title = $profile->title; // http://drupal.org/node/606364 } -function realname_content_profile_get_types() { +function content_profile_realname_get_types() { return content_profile_get_types('names'); } -function realname_content_profile_get_fields($current, $type) { +function content_profile_realname_get_fields($current, $type) { $fields = $links = array(); $all_fields = content_fields(NULL, $type); if ($all_fields) { diff --git realname_profile.inc realname_profile.inc index da6cb4c..d6562c1 100644 --- realname_profile.inc +++ realname_profile.inc @@ -5,7 +5,20 @@ * Realname module support for Profile (core) module. */ -function realname_profile_get_fields($current) { +/** + * Implementation of hook_realname(). + */ +function profile_realname() { + return array( + 'name' => 'Core Profile', + 'types' => FALSE, + 'fields' => TRUE, + 'file' => 'realname_profile.inc', + 'path' => drupal_get_path('module', 'realname'), + ); +} + +function profile_realname_get_fields($current) { $fields = $links = array(); $result = db_query("SELECT name, type, title FROM {profile_fields}"); while ($field = db_fetch_array($result)) { @@ -13,7 +26,7 @@ function realname_profile_get_fields($current) { case 'selection': case 'textfield': $name = $field['name']; - $selected = array_key_exists($name, $current); + $selected = array_key_exists($name, (array) $current); $fields[$name] = array( 'title' => $field['title'], 'weight' => $selected ? $current[$name] : 0, diff --git realname_supported.inc realname_supported.inc deleted file mode 100644 index 8c03208..0000000 --- realname_supported.inc +++ /dev/null @@ -1,20 +0,0 @@ - array( - 'name' => 'Content Profile', - 'types' => TRUE, - ), - 'profile' => array( - 'name' => 'Core Profile', - 'types' => FALSE, - ), - ); - return $list; -}