| Commit | Line | Data |
|---|---|---|
| e1a2f8a6 JC |
1 | <?php |
| 2 | // $Id$ | |
| 3 | ||
| 4 | /** | |
| 5 | * @file | |
| 0f6ca9bb | 6 | * Defines a field type for referencing a user from a node. |
| e1a2f8a6 JC |
7 | */ |
| 8 | ||
| 9 | /** | |
| 1db0519e KS |
10 | * Implementation of hook_menu(). |
| 11 | */ | |
| 12 | function userreference_menu() { | |
| 13 | $items = array(); | |
| 14 | $items['userreference/autocomplete'] = array( | |
| c56d4554 | 15 | 'title' => 'Userreference autocomplete', |
| 1db0519e KS |
16 | 'page callback' => 'userreference_autocomplete', |
| 17 | 'access arguments' => array('access content'), | |
| 18 | 'type' => MENU_CALLBACK | |
| 19 | ); | |
| 20 | return $items; | |
| 21 | } | |
| 22 | ||
| 23 | /** | |
| ea73d362 KS |
24 | * Implementation of hook_theme(). |
| 25 | */ | |
| 26 | function userreference_theme() { | |
| 27 | return array( | |
| 28 | 'userreference_select' => array( | |
| 29 | 'arguments' => array('element' => NULL), | |
| 30 | ), | |
| 4ae62d83 YC |
31 | 'userreference_buttons' => array( |
| 32 | 'arguments' => array('element' => NULL), | |
| 33 | ), | |
| ea73d362 KS |
34 | 'userreference_autocomplete' => array( |
| 35 | 'arguments' => array('element' => NULL), | |
| 36 | ), | |
| e74ada9a YC |
37 | 'userreference_formatter_default' => array( |
| 38 | 'arguments' => array('element'), | |
| 39 | ), | |
| 40 | 'userreference_formatter_plain' => array( | |
| 41 | 'arguments' => array('element'), | |
| 42 | ), | |
| ea73d362 KS |
43 | ); |
| 44 | } | |
| 45 | ||
| 46 | /** | |
| aff1f800 YC |
47 | * Implementaion of hook_ctools_plugin_directory(). |
| 48 | */ | |
| 49 | function userreference_ctools_plugin_directory($module, $plugin) { | |
| 50 | if ($module == 'ctools' && $plugin == 'relationships') { | |
| 51 | return 'panels/' . $plugin; | |
| 52 | } | |
| 53 | } | |
| 54 | ||
| 55 | /** | |
| e1a2f8a6 JC |
56 | * Implementation of hook_field_info(). |
| 57 | */ | |
| 58 | function userreference_field_info() { | |
| 59 | return array( | |
| e9b6b501 | 60 | 'userreference' => array( |
| 2400f882 KS |
61 | 'label' => t('User reference'), |
| 62 | 'description' => t('Store the ID of a related user as an integer value.'), | |
| c5482d81 | 63 | // 'content_icon' => 'icon_content_noderef.png', |
| 6d7a097b | 64 | ), |
| e1a2f8a6 JC |
65 | ); |
| 66 | } | |
| 67 | ||
| 68 | /** | |
| 69 | * Implementation of hook_field_settings(). | |
| 70 | */ | |
| e2c6522a | 71 | function userreference_field_settings($op, $field) { |
| e1a2f8a6 | 72 | switch ($op) { |
| bafef6a2 JC |
73 | case 'form': |
| 74 | $form = array(); | |
| 75 | $form['referenceable_roles'] = array( | |
| 76 | '#type' => 'checkboxes', | |
| 77 | '#title' => t('User roles that can be referenced'), | |
| 1aed1a15 | 78 | '#default_value' => isset($field['referenceable_roles']) && is_array($field['referenceable_roles']) ? array_filter($field['referenceable_roles']) : array(), |
| bafef6a2 JC |
79 | '#options' => user_roles(1), |
| 80 | ); | |
| 1db0519e | 81 | $form['referenceable_status'] = array( |
| 47abf3a7 | 82 | '#type' => 'radios', |
| 1db0519e | 83 | '#title' => t('User status that can be referenced'), |
| 01c8a292 | 84 | '#default_value' => isset($field['referenceable_status']) ? $field['referenceable_status'] : '', |
| 47abf3a7 | 85 | '#options' => array('' => t('All users'), 1 => t('Active users'), 0 => t('Blocked users')), |
| 1db0519e | 86 | ); |
| 2a1f05cb YC |
87 | if (module_exists('views')) { |
| 88 | $views = array('--' => '--'); | |
| 89 | $all_views = views_get_all_views(); | |
| 90 | foreach ($all_views as $view) { | |
| 47c2cc9e | 91 | // Only 'users' views that have fields will work for our purpose. |
| 2a1f05cb YC |
92 | if ($view->base_table == 'users' && !empty($view->display['default']->display_options['fields'])) { |
| 93 | if ($view->type == 'Default') { | |
| 94 | $views[t('Default Views')][$view->name] = $view->name; | |
| 95 | } | |
| 96 | else { | |
| 97 | $views[t('Existing Views')][$view->name] = $view->name; | |
| 98 | } | |
| 99 | } | |
| 100 | } | |
| 101 | ||
| 0e968023 YC |
102 | $form['advanced'] = array( |
| 103 | '#type' => 'fieldset', | |
| 104 | '#title' => t('Advanced - Users that can be referenced (View)'), | |
| 105 | '#collapsible' => TRUE, | |
| 106 | '#collapsed' => !isset($field['advanced_view']) || $field['advanced_view'] == '--', | |
| 107 | ); | |
| 2a1f05cb | 108 | if (count($views) > 1) { |
| 2a1f05cb YC |
109 | $form['advanced']['advanced_view'] = array( |
| 110 | '#type' => 'select', | |
| 111 | '#title' => t('View used to select the users'), | |
| 112 | '#options' => $views, | |
| 113 | '#default_value' => isset($field['advanced_view']) ? $field['advanced_view'] : '--', | |
| 0e968023 YC |
114 | '#description' => t('<p>Choose the "Views module" view that selects the users that can be referenced.<br />Note:</p>') . |
| 115 | t('<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the "Referenceable Roles" and "Referenceable Status" settings above. Use the view\'s "filters" section instead.</li><li>Use the view\'s "fields" section to display additional informations about candidate users on user creation/edition form.</li><li>Use the view\'s "sort criteria" section to determine the order in which candidate users will be displayed.</li></ul>'), | |
| 2a1f05cb YC |
116 | ); |
| 117 | $form['advanced']['advanced_view_args'] = array( | |
| 118 | '#type' => 'textfield', | |
| 119 | '#title' => t('View arguments'), | |
| 120 | '#default_value' => isset($field['advanced_view_args']) ? $field['advanced_view_args'] : '', | |
| 121 | '#required' => FALSE, | |
| 122 | '#description' => t('Provide a comma separated list of arguments to pass to the view.'), | |
| 123 | ); | |
| 124 | } | |
| 0e968023 YC |
125 | else { |
| 126 | $form['advanced']['no_view_help'] = array( | |
| 127 | '#value' => t('<p>The list of user that can be referenced can be based on a "Views module" view but no appropriate views were found. <br />Note:</p>') . | |
| 128 | t('<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the "Referenceable Roles" and "Referenceable Status" settings above. Use the view\'s "filters" section instead.</li><li>Use the view\'s "fields" section to display additional informations about candidate users on user creation/edition form.</li><li>Use the view\'s "sort criteria" section to determine the order in which candidate users will be displayed.</li></ul>'), | |
| 129 | ); | |
| 130 | } | |
| 2a1f05cb | 131 | } |
| bafef6a2 JC |
132 | return $form; |
| 133 | ||
| 134 | case 'save': | |
| 2a1f05cb YC |
135 | $settings = array('referenceable_roles', 'referenceable_status'); |
| 136 | if (module_exists('views')) { | |
| 137 | $settings[] = 'advanced_view'; | |
| 138 | $settings[] = 'advanced_view_args'; | |
| 139 | } | |
| 140 | return $settings; | |
| bafef6a2 | 141 | |
| 4af0dd2f JC |
142 | case 'database columns': |
| 143 | $columns = array( | |
| 972214b8 | 144 | 'uid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'index' => TRUE), |
| 01bf6a48 YC |
145 | ); |
| 146 | return $columns; | |
| 147 | ||
| 330807d0 KS |
148 | case 'views data': |
| 149 | $data = content_views_field_views_data($field); | |
| 150 | $db_info = content_database_info($field); | |
| f33cc12c KS |
151 | $table_alias = content_views_tablename($field); |
| 152 | ||
| 47f94b0d | 153 | // Filter : swap the handler to the 'in' operator. |
| bea5ae87 | 154 | $data[$table_alias][$field['field_name'] .'_uid']['filter']['handler'] = 'content_handler_filter_many_to_one'; |
| 017108ce YC |
155 | // Argument: get the user name for summaries. |
| 156 | // We need to join a new instance of the users table. | |
| 157 | $data["users_$table_alias"]['table']['join']['node'] = array( | |
| 158 | 'table' => 'users', | |
| 159 | 'field' => 'uid', | |
| 160 | 'left_table' => $table_alias, | |
| 161 | 'left_field' => $field['field_name'] .'_uid', | |
| 162 | ); | |
| 2a63f940 | 163 | $data[$table_alias][$field['field_name'] .'_uid']['argument']['handler'] = 'content_handler_argument_reference'; |
| 017108ce | 164 | $data[$table_alias][$field['field_name'] .'_uid']['argument']['name table'] = "users_$table_alias"; |
| d0371d94 | 165 | $data[$table_alias][$field['field_name'] .'_uid']['argument']['name field'] = 'name'; |
| 47f94b0d | 166 | // Relationship: Add a relationship for related user. |
| f33cc12c | 167 | $data[$table_alias][$field['field_name'] .'_uid']['relationship'] = array( |
| 330807d0 KS |
168 | 'base' => 'users', |
| 169 | 'field' => $db_info['columns']['uid']['column'], | |
| 0bb3edd5 | 170 | 'handler' => 'content_handler_relationship', |
| f458bc00 | 171 | 'label' => t($field['widget']['label']), |
| b6ca681f | 172 | 'content_field_name' => $field['field_name'], |
| 330807d0 KS |
173 | ); |
| 174 | return $data; | |
| 175 | ||
| e1a2f8a6 JC |
176 | } |
| 177 | } | |
| 178 | ||
| 179 | /** | |
| 180 | * Implementation of hook_field(). | |
| 181 | */ | |
| 1fbe637d KS |
182 | function userreference_field($op, &$node, $field, &$items, $teaser, $page) { |
| 183 | switch ($op) { | |
| 184 | case 'validate': | |
| 14ddf71e YC |
185 | // Extract uids to check. |
| 186 | $ids = array(); | |
| 187 | foreach ($items as $delta => $item) { | |
| 91a7f662 YC |
188 | if (is_array($item) && !empty($item['uid'])) { |
| 189 | if (is_numeric($item['uid'])) { | |
| 190 | $ids[] = $item['uid']; | |
| 191 | } | |
| 192 | else { | |
| 193 | $error_element = isset($item['_error_element']) ? $item['_error_element'] : ''; | |
| 194 | if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']); | |
| 195 | form_set_error($error_element, t('%name: invalid input.', array('%name' => t($field['widget']['label'])))); | |
| 196 | } | |
| 14ddf71e YC |
197 | } |
| 198 | } | |
| 91a7f662 YC |
199 | // Prevent performance hog if there are no ids to check. |
| 200 | if ($ids) { | |
| 201 | $refs = _userreference_potential_references($field, '', NULL, $ids); | |
| 202 | foreach ($items as $delta => $item) { | |
| 203 | if (is_array($item)) { | |
| 204 | $error_element = isset($item['_error_element']) ? $item['_error_element'] : ''; | |
| 205 | if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']); | |
| 206 | if (!empty($item['uid']) && !isset($refs[$item['uid']])) { | |
| 207 | form_set_error($error_element, t('%name: invalid user.', array('%name' => t($field['widget']['label'])))); | |
| 208 | } | |
| 24caa5e4 | 209 | } |
| 1fbe637d KS |
210 | } |
| 211 | } | |
| 14ddf71e | 212 | return $items; |
| 6130c745 KS |
213 | } |
| 214 | } | |
| e9b6b501 | 215 | |
| 6130c745 KS |
216 | /** |
| 217 | * Implementation of hook_content_is_empty(). | |
| 218 | */ | |
| 219 | function userreference_content_is_empty($item, $field) { | |
| 220 | if (empty($item['uid'])) { | |
| 221 | return TRUE; | |
| 1fbe637d | 222 | } |
| 6130c745 | 223 | return FALSE; |
| 1fbe637d | 224 | } |
| e1a2f8a6 | 225 | |
| 319350d8 | 226 | /** |
| 7e087396 | 227 | * Implementation of hook_field_formatter_info(). |
| 319350d8 | 228 | */ |
| 7e087396 KS |
229 | function userreference_field_formatter_info() { |
| 230 | return array( | |
| 231 | 'default' => array( | |
| d4353143 | 232 | 'label' => t('Default'), |
| 7e087396 | 233 | 'field types' => array('userreference'), |
| 089838e7 | 234 | 'multiple values' => CONTENT_HANDLE_CORE, |
| 7e087396 KS |
235 | ), |
| 236 | 'plain' => array( | |
| d4353143 | 237 | 'label' => t('Plain text'), |
| 7e087396 | 238 | 'field types' => array('userreference'), |
| 089838e7 | 239 | 'multiple values' => CONTENT_HANDLE_CORE, |
| 7e087396 KS |
240 | ), |
| 241 | ); | |
| 242 | } | |
| 243 | ||
| 244 | /** | |
| e74ada9a | 245 | * Theme function for 'default' userreference field formatter. |
| 7e087396 | 246 | */ |
| e74ada9a YC |
247 | function theme_userreference_formatter_default($element) { |
| 248 | $output = ''; | |
| bb471092 YC |
249 | |
| 250 | if (isset($element['#item']['uid']) && $account = user_load(array('uid' => $element['#item']['uid']))) { | |
| 251 | $output = theme('username', $account); | |
| c82e814c | 252 | } |
| e74ada9a YC |
253 | return $output; |
| 254 | } | |
| aa5d88fc | 255 | |
| e74ada9a YC |
256 | /** |
| 257 | * Theme function for 'plain' userreference field formatter. | |
| 258 | */ | |
| 259 | function theme_userreference_formatter_plain($element) { | |
| 260 | $output = ''; | |
| bb471092 | 261 | if (isset($element['#item']['uid']) && $account = user_load(array('uid' => $element['#item']['uid']))) { |
| e74ada9a | 262 | $output = $account->name; |
| 7e087396 | 263 | } |
| e74ada9a | 264 | return $output; |
| 319350d8 JC |
265 | } |
| 266 | ||
| e1a2f8a6 | 267 | /** |
| 1182d802 | 268 | * Implementation of hook_widget_info(). |
| e9b6b501 | 269 | * |
| 4ae62d83 YC |
270 | * We need custom handling of multiple values for the userreference_select |
| 271 | * widget because we need to combine them into a options list rather | |
| 272 | * than display multiple elements. | |
| e9b6b501 KS |
273 | * |
| 274 | * We will use the content module's default handling for default value. | |
| 275 | * | |
| 276 | * Callbacks can be omitted if default handing is used. | |
| 277 | * They're included here just so this module can be used | |
| 278 | * as an example for custom modules that might do things | |
| 279 | * differently. | |
| e1a2f8a6 | 280 | */ |
| 1182d802 JC |
281 | function userreference_widget_info() { |
| 282 | return array( | |
| 283 | 'userreference_select' => array( | |
| 2400f882 | 284 | 'label' => t('Select list'), |
| 1182d802 | 285 | 'field types' => array('userreference'), |
| a4418efc | 286 | 'multiple values' => CONTENT_HANDLE_MODULE, |
| e9b6b501 KS |
287 | 'callbacks' => array( |
| 288 | 'default value' => CONTENT_CALLBACK_DEFAULT, | |
| 4ae62d83 YC |
289 | ), |
| 290 | ), | |
| 291 | 'userreference_buttons' => array( | |
| 292 | 'label' => t('Check boxes/radio buttons'), | |
| 293 | 'field types' => array('userreference'), | |
| 294 | 'multiple values' => CONTENT_HANDLE_MODULE, | |
| 295 | 'callbacks' => array( | |
| 296 | 'default value' => CONTENT_CALLBACK_DEFAULT, | |
| 297 | ), | |
| 1182d802 JC |
298 | ), |
| 299 | 'userreference_autocomplete' => array( | |
| 2400f882 | 300 | 'label' => t('Autocomplete text field'), |
| 1182d802 | 301 | 'field types' => array('userreference'), |
| a4418efc | 302 | 'multiple values' => CONTENT_HANDLE_CORE, |
| e9b6b501 KS |
303 | 'callbacks' => array( |
| 304 | 'default value' => CONTENT_CALLBACK_DEFAULT, | |
| 4ae62d83 | 305 | ), |
| 1182d802 JC |
306 | ), |
| 307 | ); | |
| 308 | } | |
| e1a2f8a6 | 309 | |
| 1182d802 | 310 | /** |
| ea73d362 KS |
311 | * Implementation of FAPI hook_elements(). |
| 312 | * | |
| 313 | * Any FAPI callbacks needed for individual widgets can be declared here, | |
| 314 | * and the element will be passed to those callbacks for processing. | |
| 315 | * | |
| 316 | * Drupal will automatically theme the element using a theme with | |
| 317 | * the same name as the hook_elements key. | |
| 318 | * | |
| 319 | * Autocomplete_path is not used by text_widget but other widgets can use it | |
| 320 | * (see nodereference and userreference). | |
| 321 | */ | |
| 322 | function userreference_elements() { | |
| 323 | return array( | |
| 324 | 'userreference_select' => array( | |
| 325 | '#input' => TRUE, | |
| 326 | '#columns' => array('uid'), '#delta' => 0, | |
| 327 | '#process' => array('userreference_select_process'), | |
| 4ae62d83 YC |
328 | ), |
| 329 | 'userreference_buttons' => array( | |
| 330 | '#input' => TRUE, | |
| 331 | '#columns' => array('uid'), '#delta' => 0, | |
| 332 | '#process' => array('userreference_buttons_process'), | |
| 333 | ), | |
| ea73d362 KS |
334 | 'userreference_autocomplete' => array( |
| 335 | '#input' => TRUE, | |
| 336 | '#columns' => array('name'), '#delta' => 0, | |
| 337 | '#process' => array('userreference_autocomplete_process'), | |
| 338 | '#autocomplete_path' => FALSE, | |
| 339 | ), | |
| 340 | ); | |
| 341 | } | |
| 342 | ||
| 343 | /** | |
| 5e218086 KS |
344 | * Implementation of hook_widget_settings(). |
| 345 | */ | |
| 14ddf71e | 346 | function userreference_widget_settings($op, $widget) { |
| 5e218086 KS |
347 | switch ($op) { |
| 348 | case 'form': | |
| 349 | $form = array(); | |
| 14ddf71e | 350 | $match = isset($widget['autocomplete_match']) ? $widget['autocomplete_match'] : 'contains'; |
| 0a6df163 | 351 | $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : 60; |
| 14ddf71e YC |
352 | if ($widget['type'] == 'userreference_autocomplete') { |
| 353 | $form['autocomplete_match'] = array( | |
| 354 | '#type' => 'select', | |
| 355 | '#title' => t('Autocomplete matching'), | |
| 356 | '#default_value' => $match, | |
| 357 | '#options' => array( | |
| 358 | 'starts_with' => t('Starts with'), | |
| 359 | 'contains' => t('Contains'), | |
| 360 | ), | |
| 361 | '#description' => t('Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of users.'), | |
| 362 | ); | |
| 0a6df163 YC |
363 | $form['size'] = array( |
| 364 | '#type' => 'textfield', | |
| 365 | '#title' => t('Size of textfield'), | |
| 366 | '#default_value' => $size, | |
| 367 | '#element_validate' => array('_element_validate_integer_positive'), | |
| 368 | '#required' => TRUE, | |
| 369 | ); | |
| 14ddf71e YC |
370 | } |
| 371 | else { | |
| 372 | $form['autocomplete_match'] = array('#type' => 'hidden', '#value' => $match); | |
| bdb1b457 | 373 | $form['size'] = array('#type' => 'hidden', '#value' => $size); |
| 14ddf71e | 374 | } |
| 5e218086 | 375 | $form['reverse_link'] = array( |
| eeb67ed7 | 376 | '#type' => 'checkbox', |
| 2400f882 | 377 | '#title' => t('Reverse link'), |
| 2eb42d57 | 378 | '#default_value' => isset($widget['reverse_link']) ? $widget['reverse_link'] : 0, |
| 5e218086 KS |
379 | '#description' => t('If selected, a reverse link back to the referencing node will displayed on the referenced user record.'), |
| 380 | ); | |
| 381 | return $form; | |
| 5e218086 KS |
382 | |
| 383 | case 'save': | |
| bdb1b457 | 384 | return array('autocomplete_match', 'size', 'reverse_link'); |
| 5e218086 KS |
385 | } |
| 386 | } | |
| 387 | ||
| 388 | /** | |
| 1182d802 | 389 | * Implementation of hook_widget(). |
| e9b6b501 KS |
390 | * |
| 391 | * Attach a single form element to the form. It will be built out and | |
| 392 | * validated in the callback(s) listed in hook_elements. We build it | |
| 393 | * out in the callbacks rather than here in hook_widget so it can be | |
| 394 | * plugged into any module that can provide it with valid | |
| 395 | * $field information. | |
| 396 | * | |
| 397 | * Content module will set the weight, field name and delta values | |
| 398 | * for each form element. This is a change from earlier CCK versions | |
| 399 | * where the widget managed its own multiple values. | |
| 400 | * | |
| 401 | * If there are multiple values for this field, the content module will | |
| 402 | * call this function as many times as needed. | |
| 403 | * | |
| 404 | * @param $form | |
| 405 | * the entire form array, $form['#node'] holds node information | |
| 406 | * @param $form_state | |
| 407 | * the form_state, $form_state['values'][$field['field_name']] | |
| 408 | * holds the field's form values. | |
| 409 | * @param $field | |
| 410 | * the field array | |
| 411 | * @param $items | |
| 412 | * array of default values for this field | |
| 413 | * @param $delta | |
| 414 | * the order of this item in the array of subelements (0, 1, 2, etc) | |
| 415 | * | |
| 416 | * @return | |
| 417 | * the form item for a single element for this field | |
| 1182d802 | 418 | */ |
| e9b6b501 | 419 | function userreference_widget(&$form, &$form_state, $field, $items, $delta = 0) { |
| e9b6b501 KS |
420 | switch ($field['widget']['type']) { |
| 421 | case 'userreference_select': | |
| e9b6b501 | 422 | $element = array( |
| ea73d362 | 423 | '#type' => 'userreference_select', |
| e9b6b501 KS |
424 | '#default_value' => $items, |
| 425 | ); | |
| 426 | break; | |
| 1182d802 | 427 | |
| 4ae62d83 YC |
428 | case 'userreference_buttons': |
| 429 | $element = array( | |
| 430 | '#type' => 'userreference_buttons', | |
| 431 | '#default_value' => $items, | |
| 432 | ); | |
| 433 | break; | |
| 434 | ||
| e9b6b501 | 435 | case 'userreference_autocomplete': |
| e9b6b501 | 436 | $element = array( |
| ea73d362 | 437 | '#type' => 'userreference_autocomplete', |
| e9b6b501 KS |
438 | '#default_value' => isset($items[$delta]) ? $items[$delta] : NULL, |
| 439 | '#value_callback' => 'userreference_autocomplete_value', | |
| e9b6b501 KS |
440 | ); |
| 441 | break; | |
| 442 | } | |
| 443 | return $element; | |
| 444 | } | |
| 4af0dd2f | 445 | |
| e9b6b501 | 446 | /** |
| 92efa608 KS |
447 | * Value for a userreference autocomplete element. |
| 448 | * | |
| 449 | * Substitute in the user name for the uid. | |
| 450 | */ | |
| 451 | function userreference_autocomplete_value($element, $edit = FALSE) { | |
| 77684855 KS |
452 | $field_key = $element['#columns'][0]; |
| 453 | if (!empty($element['#default_value'][$field_key])) { | |
| 505c571a | 454 | $value = db_result(db_query("SELECT name FROM {users} WHERE uid = '%d'", $element['#default_value'][$field_key])); |
| 77684855 | 455 | return array($field_key => $value); |
| 92efa608 | 456 | } |
| 77684855 | 457 | return array($field_key => NULL); |
| 92efa608 KS |
458 | } |
| 459 | ||
| 460 | /** | |
| ea73d362 KS |
461 | * Process an individual element. |
| 462 | * | |
| 463 | * Build the form element. When creating a form using FAPI #process, | |
| 464 | * note that $element['#value'] is already set. | |
| e9b6b501 | 465 | * |
| 32ead958 | 466 | * The $fields array is in $form['#field_info'][$element['#field_name']]. |
| e9b6b501 | 467 | */ |
| ea73d362 KS |
468 | function userreference_select_process($element, $edit, $form_state, $form) { |
| 469 | // The userreference_select widget doesn't need to create its own | |
| 470 | // element, it can wrap around the optionwidgets_select element. | |
| 471 | // Add a validation step where the value can be unwrapped. | |
| 472 | $field_key = $element['#columns'][0]; | |
| 473 | $element[$field_key] = array( | |
| 474 | '#type' => 'optionwidgets_select', | |
| 443b2f04 | 475 | '#default_value' => isset($element['#value']) ? $element['#value'] : '', |
| 8c06d539 KS |
476 | // The following values were set by the content module and need |
| 477 | // to be passed down to the nested element. | |
| 8c06d539 | 478 | '#title' => $element['#title'], |
| 341f4230 | 479 | '#required' => $element['#required'], |
| 7dbb8603 | 480 | '#description' => $element['#description'], |
| 07c92176 YC |
481 | '#field_name' => $element['#field_name'], |
| 482 | '#type_name' => $element['#type_name'], | |
| 483 | '#delta' => $element['#delta'], | |
| 484 | '#columns' => $element['#columns'], | |
| ea73d362 | 485 | ); |
| 617d3264 KS |
486 | if (empty($element[$field_key]['#element_validate'])) { |
| 487 | $element[$field_key]['#element_validate'] = array(); | |
| 488 | } | |
| 489 | array_unshift($element[$field_key]['#element_validate'], 'userreference_optionwidgets_validate'); | |
| ea73d362 KS |
490 | return $element; |
| 491 | } | |
| 492 | ||
| 493 | /** | |
| 494 | * Process an individual element. | |
| 495 | * | |
| 496 | * Build the form element. When creating a form using FAPI #process, | |
| 497 | * note that $element['#value'] is already set. | |
| 498 | * | |
| 32ead958 | 499 | * The $fields array is in $form['#field_info'][$element['#field_name']]. |
| ea73d362 | 500 | */ |
| 4ae62d83 YC |
501 | function userreference_buttons_process($element, $edit, $form_state, $form) { |
| 502 | // The userreference_select widget doesn't need to create its own | |
| 503 | // element, it can wrap around the optionwidgets_select element. | |
| 504 | // Add a validation step where the value can be unwrapped. | |
| 505 | $field_key = $element['#columns'][0]; | |
| 506 | $element[$field_key] = array( | |
| 507 | '#type' => 'optionwidgets_buttons', | |
| 508 | '#default_value' => isset($element['#value']) ? $element['#value'] : '', | |
| 4ae62d83 YC |
509 | // The following values were set by the content module and need |
| 510 | // to be passed down to the nested element. | |
| 511 | '#title' => $element['#title'], | |
| 512 | '#required' => $element['#required'], | |
| 513 | '#description' => $element['#description'], | |
| 514 | '#field_name' => $element['#field_name'], | |
| 515 | '#type_name' => $element['#type_name'], | |
| 516 | '#delta' => $element['#delta'], | |
| 517 | '#columns' => $element['#columns'], | |
| 518 | ); | |
| 617d3264 KS |
519 | if (empty($element[$field_key]['#element_validate'])) { |
| 520 | $element[$field_key]['#element_validate'] = array(); | |
| 521 | } | |
| 522 | array_unshift($element[$field_key]['#element_validate'], 'userreference_optionwidgets_validate'); | |
| 4ae62d83 YC |
523 | return $element; |
| 524 | } | |
| 525 | ||
| 526 | /** | |
| 527 | * Process an individual element. | |
| 528 | * | |
| 529 | * Build the form element. When creating a form using FAPI #process, | |
| 530 | * note that $element['#value'] is already set. | |
| 531 | * | |
| 532 | */ | |
| ea73d362 KS |
533 | function userreference_autocomplete_process($element, $edit, $form_state, $form) { |
| 534 | // The userreference autocomplete widget doesn't need to create its own | |
| 535 | // element, it can wrap around the text_textfield element and add an autocomplete | |
| 536 | // path and some extra processing to it. | |
| 537 | // Add a validation step where the value can be unwrapped. | |
| 538 | $field_key = $element['#columns'][0]; | |
| 1db0519e | 539 | |
| ea73d362 KS |
540 | $element[$field_key] = array( |
| 541 | '#type' => 'text_textfield', | |
| 92efa608 | 542 | '#default_value' => isset($element['#value']) ? $element['#value'] : '', |
| 1db0519e | 543 | '#autocomplete_path' => 'userreference/autocomplete/'. $element['#field_name'], |
| 8c06d539 KS |
544 | // The following values were set by the content module and need |
| 545 | // to be passed down to the nested element. | |
| 8c06d539 | 546 | '#title' => $element['#title'], |
| 341f4230 | 547 | '#required' => $element['#required'], |
| 7dbb8603 | 548 | '#description' => $element['#description'], |
| 07c92176 YC |
549 | '#field_name' => $element['#field_name'], |
| 550 | '#type_name' => $element['#type_name'], | |
| 551 | '#delta' => $element['#delta'], | |
| 552 | '#columns' => $element['#columns'], | |
| ea73d362 | 553 | ); |
| 617d3264 KS |
554 | if (empty($element[$field_key]['#element_validate'])) { |
| 555 | $element[$field_key]['#element_validate'] = array(); | |
| 556 | } | |
| 557 | array_unshift($element[$field_key]['#element_validate'], 'userreference_autocomplete_validate'); | |
| 811e23ab | 558 | |
| 452a390c KS |
559 | // Used so that hook_field('validate') knows where to flag an error. |
| 560 | $element['_error_element'] = array( | |
| 561 | '#type' => 'value', | |
| d1eac231 | 562 | // Wrapping the element around a text_textfield element creates a |
| 617d3264 | 563 | // nested element, so the final id will look like 'field-name-0-uid-uid'. |
| 452a390c KS |
564 | '#value' => implode('][', array_merge($element['#parents'], array($field_key, $field_key))), |
| 565 | ); | |
| ea73d362 | 566 | return $element; |
| e9b6b501 | 567 | } |
| 1182d802 | 568 | |
| ea73d362 | 569 | /** |
| 4ae62d83 | 570 | * Validate a select/buttons element. |
| ea73d362 KS |
571 | * |
| 572 | * Remove the wrapper layer and set the right element's value. | |
| d30e72da KS |
573 | * We don't know exactly where this element is, so we drill down |
| 574 | * through the element until we get to our key. | |
| d1eac231 | 575 | * |
| 617d3264 KS |
576 | * We use $form_state['values'] instead of $element['#value'] |
| 577 | * to be sure we have the most accurate value when other modules | |
| 578 | * like optionwidgets are using #element_validate to alter the value. | |
| ea73d362 | 579 | */ |
| 4ae62d83 | 580 | function userreference_optionwidgets_validate($element, &$form_state) { |
| 1db0519e | 581 | $field_key = $element['#columns'][0]; |
| 14ddf71e | 582 | |
| d30e72da | 583 | $value = $form_state['values']; |
| 14ddf71e | 584 | $new_parents = array(); |
| d30e72da KS |
585 | foreach ($element['#parents'] as $parent) { |
| 586 | $value = $value[$parent]; | |
| 617d3264 KS |
587 | // Use === to be sure we get right results if parent is a zero (delta) value. |
| 588 | if ($parent === $field_key) { | |
| d30e72da | 589 | $element['#parents'] = $new_parents; |
| eeb67ed7 | 590 | form_set_value($element, $value, $form_state); |
| d30e72da KS |
591 | break; |
| 592 | } | |
| 593 | $new_parents[] = $parent; | |
| 594 | } | |
| ea73d362 KS |
595 | } |
| 596 | ||
| 597 | /** | |
| 598 | * Validate an autocomplete element. | |
| 599 | * | |
| 600 | * Remove the wrapper layer and set the right element's value. | |
| d1eac231 | 601 | * This will move the nested value at 'field-name-0-uid-uid' |
| 617d3264 | 602 | * back to its original location, 'field-name-0-uid'. |
| ea73d362 KS |
603 | */ |
| 604 | function userreference_autocomplete_validate($element, &$form_state) { | |
| 14ddf71e YC |
605 | $field_name = $element['#field_name']; |
| 606 | $type_name = $element['#type_name']; | |
| 607 | $field = content_fields($field_name, $type_name); | |
| 608 | $field_key = $element['#columns'][0]; | |
| 609 | $value = $element['#value'][$field_key]; | |
| 1db0519e | 610 | $uid = NULL; |
| 14ddf71e YC |
611 | if (!empty($value)) { |
| 612 | $reference = _userreference_potential_references($field, $value, 'equals', NULL, 1); | |
| 613 | if (empty($reference)) { | |
| 614 | form_error($element[$field_key], t('%name: found no valid user with that name.', array('%name' => t($field['widget']['label'])))); | |
| 615 | } | |
| 616 | else { | |
| 617 | $uid = key($reference); | |
| 618 | } | |
| b09a2374 | 619 | } |
| b903d4d0 | 620 | form_set_value($element, $uid, $form_state); |
| b09a2374 KS |
621 | } |
| 622 | ||
| e9b6b501 KS |
623 | /** |
| 624 | * Implementation of hook_allowed_values(). | |
| 625 | */ | |
| 626 | function userreference_allowed_values($field) { | |
| 2a1f05cb YC |
627 | $references = _userreference_potential_references($field); |
| 628 | ||
| 629 | $options = array(); | |
| 630 | foreach ($references as $key => $value) { | |
| 948f3ff9 | 631 | $options[$key] = $value['rendered']; |
| 2a1f05cb | 632 | } |
| d0c6d4fe | 633 | |
| 2a1f05cb | 634 | return $options; |
| e1a2f8a6 JC |
635 | } |
| 636 | ||
| 637 | /** | |
| 2a1f05cb YC |
638 | * Fetch an array of all candidate referenced users. |
| 639 | * | |
| 640 | * This info is used in various places (aloowed values, autocomplete results, | |
| 641 | * input validation...). Some of them only need the uids, others nid + names, | |
| 642 | * others yet uid + names + rendered row (for display in widgets). | |
| 643 | * The array we return contains all the potentially needed information, and lets | |
| 644 | * consumers use the parts they actually need. | |
| 645 | * | |
| 646 | * @param $field | |
| 647 | * The field description. | |
| 648 | * @param $string | |
| 14ddf71e YC |
649 | * Optional string to filter usernames on (used by autocomplete) |
| 650 | * @param $match | |
| 651 | * Operator to match filtered name against, can be any of: | |
| 652 | * 'contains', 'equals', 'starts_with' | |
| 653 | * @param $ids | |
| 654 | * Optional user ids to lookup (the $string and $match arguments will be | |
| 655 | * ignored). | |
| 656 | * @param $limit | |
| 657 | * If non-zero, limit the size of the result set. | |
| 2a1f05cb YC |
658 | * |
| 659 | * @return | |
| 14ddf71e | 660 | * An array of valid users in the form: |
| 2a1f05cb YC |
661 | * array( |
| 662 | * uid => array( | |
| 663 | * 'title' => The user name, | |
| 664 | * 'rendered' => The text to display in widgets (can be HTML) | |
| 665 | * ), | |
| 666 | * ... | |
| 667 | * ) | |
| 1db0519e | 668 | */ |
| 14ddf71e | 669 | function _userreference_potential_references($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) { |
| 2a1f05cb | 670 | static $results = array(); |
| 1db0519e | 671 | |
| 14ddf71e YC |
672 | // Create unique id for static cache. |
| 673 | $cid = $field['field_name'] .':'. $match .':'. ($string !== '' ? $string : implode('-', $ids)) .':'. $limit; | |
| 674 | if (!isset($results[$cid])) { | |
| 2a1f05cb YC |
675 | $references = FALSE; |
| 676 | if (module_exists('views') && !empty($field['advanced_view']) && $field['advanced_view'] != '--') { | |
| 14ddf71e | 677 | $references = _userreference_potential_references_views($field, $string, $match, $ids, $limit); |
| 2a1f05cb YC |
678 | } |
| 679 | // If the view doesn't exist, we got FALSE, and fallback to the regular 'standard mode'. | |
| 680 | ||
| 681 | if ($references === FALSE) { | |
| 14ddf71e | 682 | $references = _userreference_potential_references_standard($field, $string, $match, $ids, $limit); |
| 1db0519e | 683 | } |
| 2a1f05cb YC |
684 | |
| 685 | // Store the results. | |
| 0311a4d5 | 686 | $results[$cid] = !empty($references) ? $references : array(); |
| 1db0519e | 687 | } |
| 2a1f05cb | 688 | |
| 14ddf71e | 689 | return $results[$cid]; |
| 1db0519e KS |
690 | } |
| 691 | ||
| 692 | /** | |
| 2a1f05cb YC |
693 | * Helper function for _userreference_potential_references(): |
| 694 | * case of Views-defined referenceable users. | |
| e1a2f8a6 | 695 | */ |
| 14ddf71e | 696 | function _userreference_potential_references_views($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) { |
| 2a1f05cb YC |
697 | $view_name = $field['advanced_view']; |
| 698 | ||
| 699 | if ($view = views_get_view($view_name)) { | |
| 700 | // We add a display, and let it derive from the 'default' display. | |
| 701 | // TODO: We should let the user pick a display in the fields settings - sort of requires AHAH... | |
| 14ddf71e | 702 | $display = $view->add_display('content_references'); |
| 2a1f05cb YC |
703 | $view->set_display($display); |
| 704 | ||
| 705 | // TODO from merlinofchaos on IRC : arguments using summary view can defeat the style setting. | |
| 706 | // We might also need to check if there's an argument, and set *its* style_plugin as well. | |
| d49aafb0 | 707 | $view->display_handler->set_option('style_plugin', 'content_php_array_autocomplete'); |
| 2a1f05cb | 708 | $view->display_handler->set_option('row_plugin', 'fields'); |
| d49aafb0 YC |
709 | // Used in content_plugin_style_php_array::render(), to get |
| 710 | // the 'field' to be used as title. | |
| 711 | $view->display_handler->set_option('content_title_field', 'name'); | |
| 2a1f05cb | 712 | |
| 14ddf71e YC |
713 | // Additional options to let content_plugin_display_references::query() |
| 714 | // narrow the results. | |
| 715 | $options = array( | |
| 716 | 'table' => 'users', | |
| 717 | 'field_string' => 'name', | |
| 718 | 'string' => $string, | |
| 719 | 'match' => $match, | |
| 720 | 'field_id' => 'uid', | |
| 721 | 'ids' => $ids, | |
| 722 | ); | |
| 723 | $view->display_handler->set_option('content_options', $options); | |
| 724 | ||
| 725 | // TODO : for consistency, a fair amount of what's below | |
| 726 | // should be moved to content_plugin_display_references | |
| 727 | ||
| 728 | // Limit result set size. | |
| 7bb93942 YC |
729 | $limit = isset($limit) ? $limit : 0; |
| 730 | $view->display_handler->set_option('items_per_page', $limit); | |
| 14ddf71e | 731 | |
| 2a1f05cb YC |
732 | // Get arguments for the view. |
| 733 | if (!empty($field['advanced_view_args'])) { | |
| 734 | // TODO: Support Tokens using token.module ? | |
| 735 | $view_args = array_map('trim', explode(',', $field['advanced_view_args'])); | |
| 736 | } | |
| 737 | else { | |
| 738 | $view_args = array(); | |
| 739 | } | |
| 740 | ||
| 741 | // We do need name field, so add it if not present (unlikely, but...) | |
| 742 | $fields = $view->get_items('field', $display); | |
| 743 | if (!isset($fields['name'])) { | |
| 744 | $view->add_item($display, 'field', 'users', 'name'); | |
| 745 | } | |
| 2a1f05cb YC |
746 | |
| 747 | // If not set, make all fields inline and define a separator. | |
| 748 | $options = $view->display_handler->get_option('row_options'); | |
| 749 | if (empty($options['inline'])) { | |
| 750 | $options['inline'] = drupal_map_assoc(array_keys($view->get_items('field', $display))); | |
| 751 | } | |
| 752 | if (empty($options['separator'])) { | |
| 753 | $options['separator'] = '-'; | |
| 754 | } | |
| 755 | $view->display_handler->set_option('row_options', $options); | |
| 756 | ||
| 757 | // Make sure the query is not cached | |
| 758 | $view->is_cacheable = FALSE; | |
| 759 | ||
| 760 | // Get the results. | |
| 761 | $result = $view->execute_display($display, $view_args); | |
| 762 | } | |
| 763 | else { | |
| 764 | $result = FALSE; | |
| 765 | } | |
| 766 | ||
| 767 | return $result; | |
| 768 | } | |
| 769 | ||
| 770 | /** | |
| 771 | * Helper function for _userreference_potential_references(): | |
| 772 | * referenceable users defined by user role and status | |
| 773 | */ | |
| 14ddf71e | 774 | function _userreference_potential_references_standard($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) { |
| 1db0519e KS |
775 | $where = array(); |
| 776 | $args = array(); | |
| 777 | $join = array(); | |
| 778 | ||
| 63eb190a | 779 | if ($string !== '') { |
| 121f60a6 KS |
780 | $like = $GLOBALS["db_type"] == 'pgsql' ? "ILIKE" : "LIKE"; |
| 781 | $match_clauses = array( | |
| 782 | 'contains' => "$like '%%%s%%'", | |
| 14ddf71e | 783 | 'equals' => "= '%s'", |
| 121f60a6 | 784 | 'starts_with' => "$like '%s%%'", |
| 14ddf71e YC |
785 | ); |
| 786 | $where[] = 'u.name '. (isset($match_operators[$match]) ? $match_operators[$match] : $match_operators['contains']); | |
| 1db0519e KS |
787 | $args[] = $string; |
| 788 | } | |
| 14ddf71e YC |
789 | elseif ($ids) { |
| 790 | $where[] = 'u.uid IN (' . db_placeholders($ids) . ')'; | |
| 791 | $args = array_merge($args, $ids); | |
| e8b5d64c | 792 | } |
| 1db0519e KS |
793 | else { |
| 794 | $where[] = "u.uid > 0"; | |
| 795 | } | |
| 796 | ||
| 7e087396 | 797 | $roles = array(); |
| 24caa5e4 | 798 | if (isset($field['referenceable_roles']) && is_array($field['referenceable_roles'])) { |
| b1a2c635 YC |
799 | // keep only selected checkboxes |
| 800 | $roles = array_filter($field['referenceable_roles']); | |
| 0a1f6f8b | 801 | // filter invalid values that seems to get through sometimes ?? |
| b1a2c635 | 802 | $roles = array_intersect(array_keys(user_roles(1)), $roles); |
| 7e087396 | 803 | } |
| 1db0519e KS |
804 | if (!empty($roles) && !in_array(DRUPAL_AUTHENTICATED_RID, $roles)) { |
| 805 | $where[] = "r.rid IN (". implode($roles, ',') .")"; | |
| 806 | $join[] = 'LEFT JOIN {users_roles} r ON u.uid = r.uid'; | |
| 7e087396 | 807 | } |
| 1db0519e | 808 | |
| 47abf3a7 MFM |
809 | if (isset($field['referenceable_status']) && is_numeric($field['referenceable_status'])) { |
| 810 | $where[] = 'u.status = %d'; | |
| 811 | $args[] = $field['referenceable_status']; | |
| c4d7be16 | 812 | } |
| e1a2f8a6 | 813 | |
| 0a1f6f8b | 814 | $users = array(); |
| 14ddf71e YC |
815 | $where_clause = $where ? 'WHERE ('. implode(') AND (', $where) .')' : ''; |
| 816 | $result = db_query('SELECT u.name, u.uid FROM {users} u '. implode(' ', $join) ." $where_clause ORDER BY u.name ASC", $args); | |
| e1a2f8a6 | 817 | while ($user = db_fetch_object($result)) { |
| e7e792a6 YC |
818 | $users[$user->uid] = array( |
| 819 | 'title' => $user->name, | |
| 948f3ff9 | 820 | 'rendered' => check_plain($user->name), |
| e7e792a6 | 821 | ); |
| e1a2f8a6 | 822 | } |
| 7056e59c | 823 | return $users; |
| e1a2f8a6 | 824 | } |
| 0f6ca9bb | 825 | |
| 7056e59c | 826 | /** |
| 2a1f05cb YC |
827 | * Menu callback; Retrieve a pipe delimited string of autocomplete suggestions for existing users |
| 828 | */ | |
| 829 | function userreference_autocomplete($field_name, $string = '') { | |
| 830 | $fields = content_fields(); | |
| 831 | $field = $fields[$field_name]; | |
| 14ddf71e | 832 | $match = isset($field['widget']['autocomplete_match']) ? $field['widget']['autocomplete_match'] : 'contains'; |
| 2a1f05cb YC |
833 | $matches = array(); |
| 834 | ||
| 14ddf71e | 835 | $references = _userreference_potential_references($field, $string, $match, array(), 10); |
| 2a1f05cb YC |
836 | foreach ($references as $id => $row) { |
| 837 | // Add a class wrapper for a few required CSS overrides. | |
| 838 | $matches[$row['title']] = '<div class="reference-autocomplete">'. $row['rendered'] . '</div>'; | |
| 839 | } | |
| 840 | drupal_json($matches); | |
| 841 | } | |
| 842 | ||
| 843 | /** | |
| 5e218086 KS |
844 | * Implementation of hook_user(). |
| 845 | */ | |
| 03537a4e KS |
846 | function userreference_user($type, &$edit, &$account) { |
| 847 | switch ($type) { | |
| 5e218086 | 848 | case 'load': |
| eeb67ed7 | 849 | // Only add links if we are on the user 'view' page. |
| 28d724d1 KS |
850 | if (arg(0) != 'user' || arg(2)) { |
| 851 | return; | |
| 852 | } | |
| 48c9a6da | 853 | // find CCK userreference field tables |
| 5e218086 KS |
854 | // search through them for matching user ids and load those nodes |
| 855 | $additions = array(); | |
| 32f7c0e0 KS |
856 | $types = content_types(); |
| 857 | ||
| 858 | // Find the table and columns to search through, if the same | |
| 859 | // table comes up in more than one content type, we only need | |
| 860 | // to search it once. | |
| 861 | $search_tables = array(); | |
| 32f7c0e0 | 862 | foreach ($types as $type_name => $type) { |
| 2e55329a | 863 | foreach ($type['fields'] as $field) { |
| 28d724d1 KS |
864 | // Only add tables when reverse link has been selected. |
| 865 | if ($field['type'] == 'userreference' && !empty($field['widget']['reverse_link'])) { | |
| 32f7c0e0 | 866 | $db_info = content_database_info($field); |
| 5f1f1dec | 867 | $search_tables[$db_info['table']][] = $db_info['columns']['uid']['column']; |
| 58f22d79 | 868 | } |
| 5e218086 KS |
869 | } |
| 870 | } | |
| 5f1f1dec YC |
871 | foreach ($search_tables as $table => $columns) { |
| 872 | foreach ($columns as $column) { | |
| 873 | $ids = db_query(db_rewrite_sql("SELECT DISTINCT(n.nid), n.title, n.type FROM {node} n LEFT JOIN {". $table ."} f ON n.vid = f.vid WHERE f.". $column ."=". $account->uid. " AND n.status = 1")); | |
| 874 | while ($data = db_fetch_object($ids)) { | |
| 875 | $additions[$data->type][$data->nid] = $data->title; | |
| 876 | } | |
| 32f7c0e0 KS |
877 | } |
| 878 | } | |
| 03537a4e | 879 | $account->userreference = $additions; |
| 5e218086 KS |
880 | break; |
| 881 | ||
| 882 | case 'view': | |
| 07af053f YC |
883 | if (!empty($account->userreference)) { |
| 884 | $node_types = content_types(); | |
| 885 | $additions = array(); | |
| 03537a4e | 886 | $values = array(); |
| 07af053f | 887 | foreach ($account->userreference as $node_type => $nodes) { |
| 7533592b YC |
888 | foreach ($nodes as $nid => $title) { |
| 889 | $values[$node_type][] = l($title, 'node/'. $nid); | |
| 5e218086 | 890 | } |
| 07af053f YC |
891 | if (isset($values[$node_type])) { |
| 892 | $additions[] = array( | |
| 893 | '#type' => 'user_profile_item', | |
| 4b205056 | 894 | '#title' => check_plain($node_types[$node_type]['name']), |
| 07af053f YC |
895 | '#value' => theme('item_list', $values[$node_type]), |
| 896 | ); | |
| 897 | } | |
| 898 | } | |
| 899 | if ($additions) { | |
| 900 | $account->content['userreference'] = $additions + array( | |
| 901 | '#type' => 'user_profile_category', | |
| 902 | '#attributes' => array('class' => 'user-member'), | |
| 2400f882 | 903 | '#title' => t('Related content'), |
| 07af053f YC |
904 | '#weight' => 10, |
| 905 | ); | |
| 5e218086 | 906 | } |
| 5e218086 | 907 | } |
| 5e218086 KS |
908 | break; |
| 909 | } | |
| 910 | } | |
| 911 | ||
| ea73d362 KS |
912 | /** |
| 913 | * FAPI theme for an individual elements. | |
| 914 | * | |
| 915 | * The textfield or select is already rendered by the | |
| 4ae62d83 | 916 | * textfield or select themes and the html output |
| ea73d362 KS |
917 | * lives in $element['#children']. Override this theme to |
| 918 | * make custom changes to the output. | |
| 919 | * | |
| 920 | * $element['#field_name'] contains the field name | |
| 921 | * $element['#delta] is the position of this element in the group | |
| 922 | */ | |
| 923 | function theme_userreference_select($element) { | |
| 924 | return $element['#children']; | |
| 925 | } | |
| 926 | ||
| 4ae62d83 YC |
927 | function theme_userreference_buttons($element) { |
| 928 | return $element['#children']; | |
| 929 | } | |
| 930 | ||
| ea73d362 KS |
931 | function theme_userreference_autocomplete($element) { |
| 932 | return $element['#children']; | |
| a6e65d38 | 933 | } |