userreference.module 9.06 KB
Newer Older
1 2 3 4 5
<?php
// $Id$

/**
 * @file
6
 * Defines a field type for referencing a user from a node.
7 8 9 10 11 12 13 14
 */

/**
 * Implementation of hook_help().
 */
function userreference_help($section) {
  switch ($section) {
    case 'admin/modules#description':
15
      return t('<strong>CCK:</strong> Defines a field type for referencing a user from a node. <em>Note: Requires content.module.</em>');
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
  }
}

/**
 * Implementation of hook_field_info().
 */
function userreference_field_info() {
  return array(
    'userreference' => array('label' => 'User Reference'),
  );
}

/**
 * Implementation of hook_field_settings().
 */
JonBob's avatar
JonBob committed
31
function userreference_field_settings($op, $field) {
32
  switch ($op) {
33 34 35 36 37 38 39 40 41 42 43 44 45
    case 'form':
      $form = array();
      $form['referenceable_roles'] = array(
        '#type' => 'checkboxes',
        '#title' => t('User roles that can be referenced'),
        '#default_value' => isset($field['referenceable_roles']) ? $field['referenceable_roles'] : array(),
        '#options' => user_roles(1),
      );
      return $form;

    case 'save':
      return array('referenceable_roles');

46 47
    case 'database columns':
      $columns = array(
48
        'uid' => array('type' => 'int', 'not null' => FALSE, 'default' => NULL),
49 50
      );
      return $columns;
51 52 53 54 55 56 57 58 59 60 61

    case 'filters':
      return array(
        'default' => array(
          'list' => '_userreference_filter_handler',
          'list-type' => 'list',
          'operator' => 'views_handler_operator_or',
          'value-type' => 'array',
          'extra' => array('field' => $field),
        ),
      );
62 63 64 65 66 67
  }
}

/**
 * Implementation of hook_field().
 */
68 69 70 71
function userreference_field($op, &$node, $field, &$items, $teaser, $page) {
  switch ($op) {
    case 'validate':
      foreach ($items as $delta => $item) {
72 73 74 75
        $error_field = isset($item['error_field']) ? $item['error_field'] : '';
        unset($item['error_field']);
        if (!empty($item['uid']) && !in_array($item['uid'], array_keys(_userreference_potential_references($field)))) {
          form_set_error($error_field, t('Invalid user.'));
76 77 78 79 80
        }
      }
      return;
  }
}
81

82
/**
83
 * Implementation of hook_field_formatter_info().
84
 */
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
function userreference_field_formatter_info() {
  return array(
    'default' => array(
      'label' => 'Default',
      'field types' => array('userreference'),
    ),
    'plain' => array(
      'label' => 'Plain text',
      'field types' => array('userreference'),
    ),
  );
}

/**
 * Implementation of hook_field_formatter().
 */
function userreference_field_formatter($field, $item, $formatter, $node) {
  $text = '';
  if (isset($item['uid'])) {
    $referenced_user = user_load(array('uid' => $item['uid']));
105
    if ($referenced_user) {
106
      $text = theme('username', $referenced_user);
107
    }
108
  }
109

110 111 112
  switch ($formatter) {
    case 'plain':
      return strip_tags($text);
113

114 115 116
    default:
      return $text;
  }
117 118
}

119
/**
120
 * Implementation of hook_widget_info().
121
 */
122 123 124 125 126 127 128 129 130 131 132 133
function userreference_widget_info() {
  return array(
    'userreference_select' => array(
      'label' => 'Select List',
      'field types' => array('userreference'),
    ),
    'userreference_autocomplete' => array(
      'label' => 'Autocomplete Text Field',
      'field types' => array('userreference'),
    ),
  );
}
134

135 136 137
/**
 * Implementation of hook_widget().
 */
138
function userreference_widget($op, &$node, $field, &$items) {
139
  if ($field['widget']['type'] == 'userreference_select') {
140
    switch ($op) {
141
      case 'prepare form values':
142
        $items_transposed = content_transpose_array_rows_cols($items);
143
        // get rid of null values
144
        $items['default uids'] = array_filter((array) $items_transposed['uid']);
145 146 147 148 149
        break;

      case 'form':
        $form = array();

150
        $options = _userreference_potential_references($field);
151 152 153
        if (!$field['required']) {
          $options = array('none' => t('<none>')) + $options;
        }
154 155
        if (empty($items['default uids'])) {
          $items['default uids'][] = 'none';
156
        }
157 158
        $form[$field['field_name']] = array('#tree' => TRUE);
        $form[$field['field_name']]['uids'] = array(
159 160
          '#type' => 'select',
          '#title' => t($field['widget']['label']),
161
          '#default_value' => $items['default uids'],
162
          '#multiple' => $field['multiple'],
163
          '#size' => $field['multiple'] ? min(count($options), 6) : 0,
164
          '#options' => $options,
165
          '#required' => $field['required'],
166
          '#description' => t($field['widget']['description']),
167 168
        );

169 170
        return $form;

171
      case 'process form values':
172
        if ($field['multiple']) {
173
          // drop the 'none' option
174 175
          unset($items['uids']['none']);
          if (!empty($items['uids'])) {
176
            $items = array_values(content_transpose_array_rows_cols(array('uid' => $items['uids'])));
177 178
          }
          else {
179
            $items[0]['uid'] = '';
180
          }
181 182
        }
        else {
183
          $items[0]['uid'] = ($items['uids'] != 'none') ? $items['uids'] : '';
184
        }
185
        // Remove the widget's data representation so it isn't saved.
186
        unset($items['uids']);
187 188 189
        foreach($items as $delta => $item) {
          $items[$delta]['error_field'] =  $field['field_name'].'][uids';
        }
190 191 192 193
    }
  }
  else {
    switch ($op) {
194
      case 'prepare form values':
195 196 197
        foreach ($items as $delta => $item) {
          if (!empty($items[$delta]['uid'])) {
            $items[$delta]['default user_name'] = db_result(db_query("SELECT name FROM {users} WHERE uid = '%d'", $items[$delta]['uid']));
198
          }
199
        }
200 201
        break;

202 203 204
      case 'form':
        $form = array();
        $form[$field['field_name']] = array('#tree' => TRUE);
205 206 207

        if ($field['multiple']) {
          $form[$field['field_name']]['#type'] = 'fieldset';
208
          $form[$field['field_name']]['#description'] = t($field['widget']['description']);
209
          $delta = 0;
210
          foreach ($items as $item) {
211 212 213
            if ($item['uid']) {
              $form[$field['field_name']][$delta]['user_name'] = array(
                '#type' => 'textfield',
214
                '#title' => ($delta == 0) ? t($field['widget']['label']) : '',
215 216 217 218 219 220 221 222 223 224
                '#autocomplete_path' => 'user/autocomplete',
                '#default_value' => $item['default user_name'],
                '#required' => ($delta == 0) ? $field['required'] : FALSE,
              );
              $delta++;
            }
          }
          foreach (range($delta, $delta + 2) as $delta) {
            $form[$field['field_name']][$delta]['user_name'] = array(
              '#type' => 'textfield',
225
              '#title' => ($delta == 0) ? t($field['widget']['label']) : '',
226 227 228 229 230 231 232 233 234 235 236
              '#autocomplete_path' => 'user/autocomplete',
              '#default_value' => '',
              '#required' => ($delta == 0) ? $field['required'] : FALSE,
            );
          }
        }
        else {
          $form[$field['field_name']][0]['user_name'] = array(
            '#type' => 'textfield',
            '#title' => t($field['widget']['label']),
            '#autocomplete_path' => 'user/autocomplete',
237
            '#default_value' => $items[0]['default user_name'],
238
            '#required' => $field['required'],
239
            '#description' => t($field['widget']['description']),
240 241
          );
        }
242
        return $form;
243

244
      case 'process form values':
245
        foreach ($items as $delta => $item) {
246
          $uid = '';
247 248
          if (!empty($items[$delta]['user_name'])) {
            $uid = db_result(db_query("SELECT uid FROM {users} WHERE name = '%s'", $items[$delta]['user_name']));
249
          }
250
          // Remove the widget's data representation so it isn't saved.
251 252
          unset($items[$delta]['user_name']);
          $items[$delta]['uid'] = $uid;
253
          $items[$delta]['error_field'] = $field['field_name'].']['.$delta.'][user_name';
254
          // Don't save empty fields except the first value
255
          if (empty($uid) && $delta > 0) {
256
            unset($items[$delta]);
257
          }
258 259
        }
    }
260
  }
261 262 263 264 265 266
}

/**
 * Fetch an array of all candidate referenced users, for use in presenting the selection form to the user.
 */
function _userreference_potential_references($field) {
267
  $roles = array();
268 269 270
  if (is_array($field['referenceable_roles'])) {
    // keep only selected checkboxes
    $roles = array_filter($field['referenceable_roles']);
271
    // filter invalid values that seems to get through sometimes ??
272
    $roles = array_intersect(array_keys(user_roles(1)), $roles);
273
  }
274
  if (empty($roles) || in_array(DRUPAL_AUTHENTICATED_RID, $roles)) {
275
    $result = db_query('SELECT u.name, u.uid FROM {users} u WHERE uid > 0 ORDER BY u.name ASC');
276 277
  }
  else {
278
    $result = db_query('SELECT u.name, u.uid FROM {users} u LEFT JOIN {users_roles} r ON u.uid = r.uid WHERE u.uid > 0 AND r.rid IN ('. implode($roles, ',') .') ORDER BY u.name ASC');
279
  }
280

281
  $users = array();
282
  while ($user = db_fetch_object($result)) {
283
    $users[$user->uid] = $user->name;
284
  }
285
  return $users;
286
}
287

288 289 290 291 292
/**
 * Provide a list of users to filter on.
 */
function _userreference_filter_handler($op, $filterinfo) {
  $options = views_handler_filter_usercurrent();
293
  $options = $options + _userreference_potential_references($filterinfo['extra']['field']);
294
  return $options;
295
}