t('User titles'), 'description' => 'Configure user titles and number of posts required', 'page callback' => 'drupal_get_form', 'page arguments' => array('user_titles_settings_form'), 'access arguments' => array('administer user titles'), 'file' => 'user_titles.admin.inc', ); $items['admin/user/user-titles/settings'] = array( 'title' => t('Settings'), 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10 ); $items['admin/user/user-titles/titles'] = array( 'title' => t('Titles'), 'page callback' => 'drupal_get_form', 'page arguments' => array('user_titles_titles_form'), 'access arguments' => array('administer user titles'), 'type' => MENU_LOCAL_TASK, 'file' => 'user_titles.admin.inc', ); $items['admin/user/user-titles/add/title'] = array( 'title' => t('Add title'), 'page callback' => 'drupal_get_form', 'page arguments' => array('user_titles_add_title_form'), 'access arguments' => array('administer user titles'), 'type' => MENU_LOCAL_TASK, 'file' => 'user_titles.admin.inc', ); $items['admin/user/user-titles/edit/title/%title'] = array( 'title' => t('Edit title'), 'page callback' => 'user_titles_edit_title_form', 'page arguments' => array(5), 'access arguments' => array('administer user titles'), 'type' => MENU_CALLBACK, 'file' => 'user_titles.admin.inc', ); $items['admin/user/user-titles/delete/title/%title'] = array( 'title' => t('Remove title'), 'page callback' => 'drupal_get_form', 'page arguments' => array('user_titles_delete_title_form', 5), 'access arguments' => array('administer user titles'), 'type' => MENU_CALLBACK, 'file' => 'user_titles.admin.inc', ); $items['user-titles/autocomplete'] = array( 'title' => 'Autocomplete user titles', 'page callback' => 'user_titles_autocomplete', 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); return $items; } /** * User title wildcard loader. */ function title_load($tid) { if (!is_numeric($tid)) { return FALSE; } $title = user_titles_get_titles($tid); if (!isset($title->tid)) { return FALSE; } return $title; } /** * Implementation of hook_theme(). */ function user_titles_theme($existing, $type, $theme, $path) { return array( 'user_titles_settings_form' => array( 'arguments' => array( 'form' => array(), ), ), 'user_titles_titles_form' => array( 'arguments' => array( 'form' => array(), ), ), 'user_titles_image' => array( 'arguments' => array( 'filepath' => NULL, 'alt' => NULL, ), ), 'user_titles_matching_users_block' => array( 'arguments' => array( 'users' => array(), ), ), 'user_titles_my_title_block' => array( 'arguments' => array( 'name' => NULL, 'posts' => NULL, 'units' => NULL, 'title' => NULL, ), ), ); } /** * Implementation of hook_form_alter(). */ function user_titles_form_alter(&$form, $form_state, $form_id) { if ($form_id == 'user_admin_new_role') { $form['#submit'][] = 'user_titles_user_admin_new_role_submit'; } elseif ($form_id == 'user_admin_role') { $form['#submit'][] = 'user_titles_user_admin_role_submit'; } } /** * Extra submit handler for the user_admin_new_role form. */ function user_titles_user_admin_new_role_submit($form, &$form_state) { if ($form_state['values']['op'] == t('Add role')) { $max_weight = db_result(db_query("SELECT MAX(weight) FROM {user_titles_roles}")); db_query("INSERT INTO {user_titles_roles} (rid, weight) SELECT rid, %d FROM {role} WHERE name = '%s'", $max_weight + 1, $form_state['values']['name']); } } /** * Extra submit handler for the user_admin_role form. */ function user_titles_user_admin_role_submit($form, &$form_state) { if ($form_state['values']['op'] == t('Delete role')) { db_query("DELETE FROM {user_titles_roles} WHERE rid = %d", $form_state['values']['rid']); } } /** * Implementation of hook_block(). */ function user_titles_block($op = 'list', $delta = 0, $edit = array()) { switch ($op) { case 'list': $blocks[0] = array( 'info' => t('User Titles: Users with my title'), 'cache' => BLOCK_CACHE_PER_USER, ); $blocks[1] = array( 'info' => t('User Titles: My title'), 'cache' => BLOCK_CACHE_PER_USER, ); return $blocks; case 'view': // If $op is "view", then we need to generate the block for display // purposes. The $delta parameter tells us which block is being requested. switch ($delta) { case 0: $block['subject'] = t('Users with your title'); $block['content'] = user_titles_matching_users_block(); break; case 1: $block['subject'] = t('My title'); $block['content'] = user_titles_my_title_block(); break; } // End delta switch return $block; case 'configure': $form = array(); switch ($delta) { case 0: $options = array(); for ($i = 1; $i <= 25; $i++) { $options[$i] = $i; } $form['number_users'] = array( '#type' => 'select', '#title' => t('Max number of users to display'), '#default_value' => variable_get('user_titles_block_number_users', 10), '#options' => $options, ); break; case 1: $form['display_fields'] = array( '#type' => 'select', '#title' => t('Fields to display'), '#default_value' => variable_get('user_titles_block_display_fields', array('name', 'posts', 'title')), '#options' => array( 'name' => t('Name'), 'posts' => t('Posts'), 'title' => t('Title'), ), '#multiple' => TRUE, '#required' => TRUE, ); break; } // End delta switch return $form; case 'save': switch ($delta) { case 0: variable_set('user_titles_block_number_users', $edit['number_users']); break; case 1: variable_set('user_titles_block_display_fields', $edit['display_fields']); break; } // End delta switch } // End op switch } /** * Creates the content for a block that lists users with your title. * Displays random users with the same title as you. * * @return * A string containing the html output for the matching users block. */ function user_titles_matching_users_block() { global $user; $users = user_titles_get_matching_users($user); if (!empty($users)) { shuffle($users); $count = min(variable_get('user_titles_block_number_users', 10), count($users)); $users = array_slice($users, 0, $count - 1, TRUE); foreach ($users as $key => $user) { $users[$key] = user_load($user); } } return theme('user_titles_matching_users_block', $users); } /** * Creates the content for a block that lists the current user's title. * * @return * A string containing the html output for the my title block. */ function user_titles_my_title_block() { drupal_add_css(drupal_get_path('module', 'user_titles') . '/user_titles.css'); global $user; // Only display fields that the block settings say to $display_fields = variable_get('user_titles_block_display_fields', array('name', 'posts', 'title')); $name = isset($display_fields['name']) ? $user->name : NULL; $posts = isset($display_fields['posts']) ? user_titles_get_posts($user->uid) : NULL; $units = isset($display_fields['posts']) ? module_invoke(variable_get('user_titles_hook_module', 'ut_basic'), 'user_titles', 'units') : NULL; $title = isset($display_fields['title']) ? user_titles_get_user_title($user) : NULL; return theme('user_titles_my_title_block', $name, $posts, $units, $title); } /** * Implementation of hook_user(). * * Add the 'edit user title' form to the edit user page. */ function user_titles_user($op, $edit, &$user, $category = NULL) { switch ($op) { case 'form': if (user_access('administer user titles') && $category == 'account' && (isset($user->uid))) { // when user tries to edit his own data $form['user_titles'] = array( '#type' => 'fieldset', '#title' => t('User Title'), '#collapsible' => TRUE, '#weight' => 4, ); $title_info = user_titles_get_user_title_info($user); if (!isset($title_info->title)) { $title = t('No title set'); } else { $title = $title_info->title; } $form['user_titles']['current_title'] = array( '#value' => '
' . t('Current user title:') . ' ' . filter_xss_admin($title) . '
', ); if (isset($title_info->title) && empty($title_info->tid)) { $default_title_info = user_titles_get_title(user_titles_get_posts($uid)); if (!isset($default_title_info->title)) { $default_title = t('No title set'); } else { $default_title = $default_title_info->title; } $form['user_titles']['default_title'] = array( '#value' => '
' . t('Default user title:') . ' ' . filter_xss_admin($default_title) . '
', ); } $form['user_titles']['user_title'] = array( '#type' => 'textfield', '#title' => t('Override title'), '#description' => t('Enter a title here to give this user a manually overridden title. Leave blank to use the default title.'), '#default_value' => isset($user->user_title) ? $user->user_title : '', ); return $form; } break; case 'view': if (variable_get('user_titles_display_on_profile', TRUE)) { $title = user_titles_get_user_title($user); if ($title) { $user->content['user_titles'] = array( '#type' => 'user_profile_category', '#title' => t('User title'), ); $user->content['user_titles']['title'] = array( '#type' => 'user_profile_item', '#value' => filter_xss_admin($title), ); } } break; } } /** * Get the number of posts for a user. * If we don't have a stored count in the database, count and store that value. * * @todo When porting to 7.x, rename to user_title_get_points. * * @param $uid * An integer containing the uid of the user to fetch the number of posts for. * * @return * An integer containing the number of posts for the user. */ function user_titles_get_posts($uid) { static $cache = array(); if (!isset($cache[$uid])) { $module = variable_get('user_titles_hook_module', 'ut_basic'); $cache[$uid] = module_invoke($module, 'user_titles', 'get', $uid); } return $cache[$uid]; } /** * Calculate a title based upon the number of posts and user role. * * @param $posts * The number of posts to find the title for. * @param $rid * The role id to get the title for. * If $rid is NULL the default user titles role will be used. * * @return * A title object for the number of posts and role. */ function user_titles_get_title($posts, $rid = NULL) { if (!$rid) { $rid = user_titles_get_default_role(); } $titles = user_titles_get_titles_by_role($rid); // This array will be sorted from highest to lowest prior to storing. foreach ($titles as $title) { if ($posts >= $title->value) { return $title; } } } /** * Fetch a title for the given user. * * @param $user * The user to fetch the title for. May be a $user object or a $uid. */ function user_titles_get_user_title($user) { $title = user_titles_get_user_title_info($user); if (isset($title->title)) { return $title->title; } } /** * Fetch the user title image path for the given user. * * @param $user * The user to fetch the image path for. May be a $user object or a $uid. */ function user_titles_get_user_image_path($user) { $title = user_titles_get_user_title_info($user); if (isset($title->image)) { return $title->image; } } /** * Fetch the themed user title image for the given user. * * @param $user * The user to fetch the image for. May be a $user object or a $uid. */ function user_titles_get_user_image($user) { $title = user_titles_get_user_title_info($user); if (isset($title->image)) { return theme('user_titles_image', $title->image, $title->image_title); } } /** * Fetch full title info for a given user. * * @param $user * The user to fetch. May be a $user object or a $uid. * * @return * The title object for the user. */ function user_titles_get_user_title_info($user) { if (is_numeric($user)) { $user = user_load(array('uid' => $user)); } if (!$user) { return; } // Return override title if set. if (!empty($user->user_title)) { $title = new stdClass; $title->title = $user->user_title; return $title; } $tid = db_query("SELECT tid FROM {user_titles_users} WHERE uid = %d", $user->uid); $title = user_titles_get_titles($tid); return $title; } /** * Get the title id for the given user. * * @param $uid * The user id to get the tid for. * * @return * The tid of the users title. */ function user_titles_get_user_tid($uid) { $rid = user_titles_get_user_title_role($uid); $title = user_titles_get_title(user_titles_get_posts($uid), $rid); return $title->tid ? $title->tid : 0; } /** * Get users (uids) that have a given title in a given role. * * @param $user * The user object to fetch the matching users for. * * @return * An array of user ids */ function user_titles_get_matching_users($user) { $users = array(); $title = user_titles_get_user_title_info($user->uid); if ($title->tid) { $result = db_query("SELECT uid FROM {user_titles_users} WHERE tid = %d AND uid != %d", $title->tid, $user->uid); while ($row = db_fetch_array($result)) { $users[] = $row['uid']; } } return $users; } /** * Get titles from db * If tid is passed in only that title will be fetched, otherwise all titles will be fetched. * * @param $tid * The title id to retrieve. If NULL then fetch all titles. * * @return * If $tid param is not NULL a title object is returned. * Otherwise an array of title objects is returned. */ function user_titles_get_titles($tid = NULL) { if ($tid && is_numeric($tid)) { $result = db_fetch_object(db_query("SELECT * FROM {user_titles} WHERE tid = %d", $tid)); } else { $result = array(); $query = db_query("SELECT * FROM {user_titles} ORDER BY value DESC"); while ($row = db_fetch_object($query)) { $result[] = $row; } } return $result; } /** * Get titles from db based on rid * If rid is passed in only that roles titles will be fetched, * otherwise all titles will be fetched and ordered by role then value * * @param $rid * The role id to get the titles for. If NULL return all titles. * * @return * An array of title objects. */ function user_titles_get_titles_by_role($rid = NULL) { $result = array(); if ($rid) { $query = db_query("SELECT * FROM {user_titles} WHERE rid = %d ORDER BY value DESC", $rid); } else { $query = db_query("SELECT * FROM {user_titles} ORDER BY rid, value DESC"); } while ($row = db_fetch_object($query)) { $result[] = $row; } return $result; } /** * Get an array of the roles available for user_titles ordered by weight. * * @return * An array of roles with role id as the key and role name as the value. */ function user_titles_get_roles() { $roles = array(); $result = db_query("SELECT r.rid, r.name FROM {role} r, {user_titles_roles} ur WHERE r.rid = ur.rid ORDER BY ur.weight"); while ($row = db_fetch_array($result)) { $roles[$row['rid']] = $row['name']; } return $roles; } /** * Get the default role in case a role is not specified somewhere. * The default role is the role with the least weight. * * @return * An integer containing a role id. */ function user_titles_get_default_role() { $rid = db_result(db_query_range("SELECT rid FROM {user_titles_roles} ORDER BY weight", 0, 1)); return $rid; } /** * Get the role that is to be used for a users titles. * * @return * An integer containing a role id. */ function user_titles_get_user_title_role($uid) { $rid = db_result(db_query_range("SELECT rid FROM {user_titles_roles} WHERE rid IN (SELECT rid FROM {users_roles} WHERE uid = %d) OR rid = 2 ORDER BY weight", $uid, 0, 1)); return $rid; } /** * Set the given users title * * @param $uid * The user id to set the title for. */ function user_titles_set_user_title($uid) { $tid = user_titles_get_user_tid($uid); db_query("UPDATE {user_titles_users} SET tid = %d WHERE uid = %d", $tid, $uid); if (!db_affected_rows()) { db_query("INSERT INTO {user_titles_users} (uid, tid) VALUES (%d, %d)", $uid, $tid); } } /** * Reset all user titles */ function user_titles_reset_titles() { // Just in case. This could take a little while... set_time_limit(600); db_query('TRUNCATE TABLE {user_titles_users}'); $result = db_query('SELECT uid FROM {users}'); $uids = array(); while ($row = db_fetch_array($result)) { $uids[] = $row['uid']; } foreach ($uids as $uid) { user_titles_set_user_title($uid); } } /** * Theme function for user titles images. * * @param $filepath * A string containing the filepath of the image * @param $alt * A string containing the alt text for the image. Also used for the image title. * * @return * A string containing the html output for the user titles image. * * @ingroup themeable */ function theme_user_titles_image($filepath, $alt) { $image = theme('image', $filepath, $alt, $alt, '', FALSE); $output = '
'; $output .= $image; $output .= '
'; return $output; } /** * Theme function for the matching users block * * @param $users * An array of user objects. * * @ingroup themeable */ function theme_user_titles_matching_users_block($users = array()) { $output = ''; if (!empty($users)) { $output = ''; } else { $output .= '' . t('There are no other uses with your title.') . ''; } return $output; } /** * Theme function for the my title block * * @param $name * A string containing the users name. * @param $posts * An integer containing the number of user posts. * @param $units * A string containing the units of the posts. * @param $title * A string containing the users title. * * @ingroup themeable */ function theme_user_titles_my_title_block($name = NULL, $posts = NULL, $units = NULL, $title = NULL) { $output = ''; if (!is_null($name) || !is_null($posts) || !is_null($title)) { $label_class = 'label'; $value_class = 'value'; $output .= ''; $output .= ''; if (!is_null($name)) { $output .= ''; } if (!is_null($posts)) { $output .= ''; } if (!is_null($title)) { $output .= ''; } $output .= '
'; $output .= t('Name:'); $output .= ''; $output .= $name; $output .= '
'; $output .= "$units:"; $output .= ''; $output .= $posts; $output .= '
'; $output .= t('Title:'); $output .= ''; $output .= $title ? $title : t('No title'); $output .= '
'; } return $output; } /** * Implementation of template_preprocess_node(). */ function user_titles_preprocess_node(&$variables) { $variables['user_title'] = user_titles_get_user_title($variables['node']->uid); $variables['user_title_image'] = user_titles_get_user_image($variables['node']->uid); } /** * Implementation of template_preprocess_comment(). */ function user_titles_preprocess_comment(&$variables) { $variables['user_title'] = user_titles_get_user_title($variables['comment']->uid); $variables['user_title_image'] = user_titles_get_user_image($variables['comment']->uid); } /** * Helper function for autocompletion */ function user_titles_autocomplete($rids, $string = '') { // The user enters a comma-separated list of titles. We only autocomplete the last title. $array = drupal_explode_tags($string); $rids = explode(',', $rids); foreach ($rids as $rid) { $in .= $in ? ', %d' : '%d'; $query_vars[] = $rid; } // Fetch last tag $last_string = trim(array_pop($array)); $query_vars[] = $last_string; $matches = array(); if ($last_string != '') { $result = db_query_range("SELECT tid, title FROM {user_titles} WHERE rid IN ($in) AND LOWER(title) LIKE LOWER('%%%s%%')", $query_vars, 0, 10); $prefix = count($array) ? implode(', ', $array) . ', ' : ''; while ($title = db_fetch_object($result)) { $t = $title->title; // Commas and quotes in terms are special cases, so encode 'em. if (strpos($title->title, ',') !== FALSE || strpos($title->title, '"') !== FALSE) { $t = '"' . str_replace('"', '""', $title->title) . '"'; } $matches[$prefix . $t] = check_plain($title->title); } } drupal_json($matches); }