Drupal @ CSU
atrium_username feature
               Emanuele Quinto
     Identity Management/Portal
atrium_username




2
atrium_username
     • a Drupal feature for managing user name display;
     • a lightweight alternative to realname module;
     • "works" before theme layer
     • uses the node title of the user profile
    function atrium_username_get_name($uid) {
      static $users = array();
      if (!isset($users[$uid])) {
        // get data from db DIRECTLY
        $users[$uid] = db_result(db_query("SELECT title
    FROM {node} WHERE type='profile' AND uid=%d", $uid));
      }
      return $users[$uid];
    }

    It doesn't implements its own theme_username allowing another theme to
                                    override it.
3
Account Block




4
Account Block




5
Account Block
 Preprocess injection
  // Preprocess block.
  // Inject custom preprocessor before tao/ginkgo.
  $preprocess_function = $theme_registry['block']
['preprocess functions'];
  $preprocess_theme = array_slice($preprocess_function,
2);
  array_unshift($preprocess_theme,
'atrium_username_preprocess_block');
  array_splice($preprocess_function, 2,
count($preprocess_function), $preprocess_theme);

  $theme_registry['block']['preprocess functions'] =
$preprocess_function;
  $theme_registry['block']['include files'][] =
$atrium_username_path . '/atrium_username.theme.inc';

     Insert atrium_username_preprocess_block before other preprocess
 6
Account Block
 Preprocess implementation
        function atrium_username_preprocess_block(&$variables)
{
  // atrium-account
  if($variables['block']->bid == "atrium-account") {
    global $user;
    if ($user->uid) {
       $atrium_username = atrium_username_get_name($user-
>uid);
       $user_name = $atrium_username ? $atrium_username :
check_plain($user->name);
       $variables['block']->subject =
theme('user_picture', $user) . $user_name;
    }
  }
}

                   Don't use theme_username, it adds a link!
    7
User Profile




8
User Profile




9
User Profile

Hook views_pre_render

function atrium_username_views_pre_render(&$view) {

  // set title for profile_display
(http://drupal.org/node/1176080)
  if($view->name == 'profile_display' && $view-
>current_display == 'page_1') {
    $uid = $view->args[0];
    $atrium_username = atrium_username_get_name($uid);
    if(!empty($atrium_username)) {
      drupal_set_title($atrium_username);
    }
  }
}



 10
User Name Field




11
User Name Field




12
User Name Field
 render_link() method
function render_link($data, $values) {

       // get uid field name
       $field_uid = isset($this->aliases['uid']) ? $this->aliases['uid'] : 'uid';

    if (!empty($this->options['link_to_user']) || !empty($this-
>options['overwrite_anonymous'])) {
      $account = new stdClass();
      $account->uid = $values->{$field_uid};
      if (!empty($this->options['overwrite_anonymous']) && !$account->uid) {
         // This is an anonymous user, and we're overriting the text.
         return check_plain($this->options['anonymous_text']);
      }
      elseif (!empty($this->options['link_to_user'])) {
         $account->name = $values->{$this->field_alias};
         return theme('username', $account);
      }
    }
    // Otherwise, there's no special handling, so try to return atrium_username.
    if(isset($values->{$field_uid})) {
      $atrium_username = atrium_username_get_name($values->{$field_uid});
      return $atrium_username ? $atrium_username : $data;
    }
    else {
        return $data;
    }
  }


  13
Casetracker




14
Casetracker – issue page




15
Casetracker – issue page

 Function atrium_username_theme_casetracker_comment_changes

case 'assign_to':
  $old->{$field} = atrium_username_get_name($old-
>{$field}) ? atrium_username_get_name($old->{$field}) :
check_plain(casetracker_get_name($old->{$field}));
  $new->{$field} = atrium_username_get_name($new-
>{$field}) ? atrium_username_get_name($new->{$field}) :
check_plain(casetracker_get_name($new->{$field}));
  break;




 Unfortunately we have to rewrite everything as the lines to be changed are
                inside a switch/case with no other options.
                   Only the case 'assign_to' is modified.

 16
Casetracker – assign to




17
Casetracker – issue page
 hook_form_alter
if(!empty($form['casetracker']['assign_to']['#options'])) {
       $assign_to = $form['casetracker']['assign_to']
['#options'];
       foreach($assign_to as $key => $value) {
         $uid = casetracker_get_uid($key);
         $atrium_username = atrium_username_get_name($uid);
         $name = $atrium_username ? $atrium_username : $value;
         $form['casetracker']['assign_to']['#options'][$key] =
$name;
       }
    }




                   Radio options are set at theme level
        (theme_casetracker_case_form_common) but this is a form
              (comment_form()) so we can hook_form_alter:

 18
Casetracker – issue filter




19
Casetracker – issue filter
 hook_form_alter
 if($form_id=='views_exposed_form' && $form['#id']=='views-
exposed-form-casetracker-cases-page-1') {
    foreach($form['assign_to']['#options'] as $uid => $value) {
      if(is_int($uid) && $uid>0) {
        $atrium_username = atrium_username_get_name($uid);
        if(!empty($atrium_username)) {
          $form['assign_to']['#options'][$uid] =
$atrium_username . "~";
        }
      }
    }
  }



  The "Filter results" block is an exposed filter from the casetracker_cases​
                                                           ​
                                      view.
       It's a form so we user hook_form_alter to modify user names

 20
Casetracker – assigned column




21
Casetracker – assigned column
    Override field handler
class atrium_username_casetracker_views_handler_field_user_name
extends views_handler_field {

  function render($values) {
    $uid = $values->{$this->field_alias};
    if($uid==0) {
      return casetracker_get_name($uid);
    }
    else {
      $atrium_username = atrium_username_get_name($uid);
      return $atrium_username ? $atrium_username :
casetracker_get_name($uid);
    }
  }

}

         Override Casetracker Module implementation of views_handler_field
                   (casetracker_views_handler_field_user_name):
    22
Theming User Name




23
Theming User Name




24
Theming User Name
 Simulate preprocess
// Simulate a preprocess function for theme("username").
  $_SESSION['theme_registry_username_function'] =
$theme_registry['username']['function'];
  $theme_registry['username']['function'] =
'atrium_username_preprocess_username';
  $theme_registry['username']['include files'] =
array($atrium_username_path '/atrium_username.theme.inc');


       Override theme but apply original theme (saved in $_SESSION)

function atrium_username_preprocess_username($object) {
 $theme_username = $_SESSION['theme_registry_username_function'] ?
$_SESSION['theme_registry_username_function'] : 'theme_username';
  $user = drupal_clone($object);
  if($user->uid) {
    $atrium_username = atrium_username_get_name($user->uid);
    $user->name = $atrium_username ? $atrium_username : $user->name;
  }
  return $theme_username($user);}

 25
Notifications




26
Notifications




27
Notifications
 hook_form_alter
// Change notification_team form options
  if(!empty($form['notifications']['notifications_team']
['options']['#value'])) {
    foreach($form['notifications']['notifications_team']
['options']['#value'] as $uid => $name) {
      $atrium_username = atrium_username_get_name($uid);
      $name = $atrium_username ? $atrium_username : $name;
      $form['notifications']['notifications_team']['options']
['#value'][$uid] = $name;
    }
  }




 28
Autocomplete




29
Notifications




30
Autocomplete
    hook_menu_alter
function atrium_username_menu_alter(&$callbacks) {
  $callbacks['members/add/autocomplete']['page callback'] = 'atrium_username_autocomplete';
  $callbacks['members/add/ajax']['page callback'] = 'atrium_username_addform_ajax';
}



    callback
function atrium_username_autocomplete($string = '') {
  $matches = array();
  if ($string) {
    $query = "SELECT u.uid, u.name, n.title
              FROM {users} u LEFT JOIN {node} n ON (n.uid=u.uid AND n.type='profile')
              WHERE LOWER(n.title) LIKE LOWER('%s%%') OR LOWER(u.name) LIKE LOWER('%s%%')";
    $query = db_rewrite_sql($query, 'users', 'uid', array($string, $string));

         $result = db_query_range($query, array($string, $string), 0, 10);
         while ($user = db_fetch_object($result)) {
           $user_name = $user->title ? check_plain($user->title) : check_plain($user->name);
           $matches[$user_name] = $user_name;
         }
    }
    drupal_json($matches);
}




    31
Files




32
Q&A

     Thank you
33
About




                             Emanuele Quinto
                                    equinto@sfsu.edu
             http://www.linkedin.com/in/emanuelequinto
                                              @emaV


                              atrium_username
              http://drupal.org/project/atrium_username
             https://github.com/emaV/atrium_username
34

Drupal csu-open atriumname

  • 1.
    Drupal @ CSU atrium_usernamefeature Emanuele Quinto Identity Management/Portal
  • 2.
  • 3.
    atrium_username • a Drupal feature for managing user name display; • a lightweight alternative to realname module; • "works" before theme layer • uses the node title of the user profile function atrium_username_get_name($uid) { static $users = array(); if (!isset($users[$uid])) { // get data from db DIRECTLY $users[$uid] = db_result(db_query("SELECT title FROM {node} WHERE type='profile' AND uid=%d", $uid)); } return $users[$uid]; } It doesn't implements its own theme_username allowing another theme to override it. 3
  • 4.
  • 5.
  • 6.
    Account Block Preprocessinjection // Preprocess block. // Inject custom preprocessor before tao/ginkgo. $preprocess_function = $theme_registry['block'] ['preprocess functions']; $preprocess_theme = array_slice($preprocess_function, 2); array_unshift($preprocess_theme, 'atrium_username_preprocess_block'); array_splice($preprocess_function, 2, count($preprocess_function), $preprocess_theme); $theme_registry['block']['preprocess functions'] = $preprocess_function; $theme_registry['block']['include files'][] = $atrium_username_path . '/atrium_username.theme.inc'; Insert atrium_username_preprocess_block before other preprocess 6
  • 7.
    Account Block Preprocessimplementation function atrium_username_preprocess_block(&$variables) { // atrium-account if($variables['block']->bid == "atrium-account") { global $user; if ($user->uid) { $atrium_username = atrium_username_get_name($user- >uid); $user_name = $atrium_username ? $atrium_username : check_plain($user->name); $variables['block']->subject = theme('user_picture', $user) . $user_name; } } } Don't use theme_username, it adds a link! 7
  • 8.
  • 9.
  • 10.
    User Profile Hook views_pre_render functionatrium_username_views_pre_render(&$view) { // set title for profile_display (http://drupal.org/node/1176080) if($view->name == 'profile_display' && $view- >current_display == 'page_1') { $uid = $view->args[0]; $atrium_username = atrium_username_get_name($uid); if(!empty($atrium_username)) { drupal_set_title($atrium_username); } } } 10
  • 11.
  • 12.
  • 13.
    User Name Field render_link() method function render_link($data, $values) { // get uid field name $field_uid = isset($this->aliases['uid']) ? $this->aliases['uid'] : 'uid'; if (!empty($this->options['link_to_user']) || !empty($this- >options['overwrite_anonymous'])) { $account = new stdClass(); $account->uid = $values->{$field_uid}; if (!empty($this->options['overwrite_anonymous']) && !$account->uid) { // This is an anonymous user, and we're overriting the text. return check_plain($this->options['anonymous_text']); } elseif (!empty($this->options['link_to_user'])) { $account->name = $values->{$this->field_alias}; return theme('username', $account); } } // Otherwise, there's no special handling, so try to return atrium_username. if(isset($values->{$field_uid})) { $atrium_username = atrium_username_get_name($values->{$field_uid}); return $atrium_username ? $atrium_username : $data; } else { return $data; } } 13
  • 14.
  • 15.
  • 16.
    Casetracker – issuepage Function atrium_username_theme_casetracker_comment_changes case 'assign_to': $old->{$field} = atrium_username_get_name($old- >{$field}) ? atrium_username_get_name($old->{$field}) : check_plain(casetracker_get_name($old->{$field})); $new->{$field} = atrium_username_get_name($new- >{$field}) ? atrium_username_get_name($new->{$field}) : check_plain(casetracker_get_name($new->{$field})); break; Unfortunately we have to rewrite everything as the lines to be changed are inside a switch/case with no other options. Only the case 'assign_to' is modified. 16
  • 17.
  • 18.
    Casetracker – issuepage hook_form_alter if(!empty($form['casetracker']['assign_to']['#options'])) { $assign_to = $form['casetracker']['assign_to'] ['#options']; foreach($assign_to as $key => $value) { $uid = casetracker_get_uid($key); $atrium_username = atrium_username_get_name($uid); $name = $atrium_username ? $atrium_username : $value; $form['casetracker']['assign_to']['#options'][$key] = $name; } } Radio options are set at theme level (theme_casetracker_case_form_common) but this is a form (comment_form()) so we can hook_form_alter: 18
  • 19.
  • 20.
    Casetracker – issuefilter hook_form_alter if($form_id=='views_exposed_form' && $form['#id']=='views- exposed-form-casetracker-cases-page-1') { foreach($form['assign_to']['#options'] as $uid => $value) { if(is_int($uid) && $uid>0) { $atrium_username = atrium_username_get_name($uid); if(!empty($atrium_username)) { $form['assign_to']['#options'][$uid] = $atrium_username . "~"; } } } } The "Filter results" block is an exposed filter from the casetracker_cases​ ​ view. It's a form so we user hook_form_alter to modify user names 20
  • 21.
  • 22.
    Casetracker – assignedcolumn Override field handler class atrium_username_casetracker_views_handler_field_user_name extends views_handler_field { function render($values) { $uid = $values->{$this->field_alias}; if($uid==0) { return casetracker_get_name($uid); } else { $atrium_username = atrium_username_get_name($uid); return $atrium_username ? $atrium_username : casetracker_get_name($uid); } } } Override Casetracker Module implementation of views_handler_field (casetracker_views_handler_field_user_name): 22
  • 23.
  • 24.
  • 25.
    Theming User Name Simulate preprocess // Simulate a preprocess function for theme("username"). $_SESSION['theme_registry_username_function'] = $theme_registry['username']['function']; $theme_registry['username']['function'] = 'atrium_username_preprocess_username'; $theme_registry['username']['include files'] = array($atrium_username_path '/atrium_username.theme.inc'); Override theme but apply original theme (saved in $_SESSION) function atrium_username_preprocess_username($object) { $theme_username = $_SESSION['theme_registry_username_function'] ? $_SESSION['theme_registry_username_function'] : 'theme_username'; $user = drupal_clone($object); if($user->uid) { $atrium_username = atrium_username_get_name($user->uid); $user->name = $atrium_username ? $atrium_username : $user->name; } return $theme_username($user);} 25
  • 26.
  • 27.
  • 28.
    Notifications hook_form_alter // Changenotification_team form options if(!empty($form['notifications']['notifications_team'] ['options']['#value'])) { foreach($form['notifications']['notifications_team'] ['options']['#value'] as $uid => $name) { $atrium_username = atrium_username_get_name($uid); $name = $atrium_username ? $atrium_username : $name; $form['notifications']['notifications_team']['options'] ['#value'][$uid] = $name; } } 28
  • 29.
  • 30.
  • 31.
    Autocomplete hook_menu_alter function atrium_username_menu_alter(&$callbacks) { $callbacks['members/add/autocomplete']['page callback'] = 'atrium_username_autocomplete'; $callbacks['members/add/ajax']['page callback'] = 'atrium_username_addform_ajax'; } callback function atrium_username_autocomplete($string = '') { $matches = array(); if ($string) { $query = "SELECT u.uid, u.name, n.title FROM {users} u LEFT JOIN {node} n ON (n.uid=u.uid AND n.type='profile') WHERE LOWER(n.title) LIKE LOWER('%s%%') OR LOWER(u.name) LIKE LOWER('%s%%')"; $query = db_rewrite_sql($query, 'users', 'uid', array($string, $string)); $result = db_query_range($query, array($string, $string), 0, 10); while ($user = db_fetch_object($result)) { $user_name = $user->title ? check_plain($user->title) : check_plain($user->name); $matches[$user_name] = $user_name; } } drupal_json($matches); } 31
  • 32.
  • 33.
    Q&A Thank you 33
  • 34.
    About Emanuele Quinto equinto@sfsu.edu http://www.linkedin.com/in/emanuelequinto @emaV atrium_username http://drupal.org/project/atrium_username https://github.com/emaV/atrium_username 34